http 总结
http定义
http 是 超文本传输协议(HyperText Transfer Protocol)的缩写,它是互联网上应用最为广泛的一种网络协议。
七层网络模型(推荐好文:https://www.cnblogs.com/Robin-YB/p/6668762.html)
OSI七层网络模型 |
TCP/IP四层概念模型 |
对应网络协议 |
应用层(Application) |
应用层 |
HTTP、TFTP, FTP, NFS, WAIS、SMTP |
表示层(Presentation) |
Telnet, Rlogin, SNMP, Gopher |
|
会话层(Session) |
SMTP, DNS |
|
传输层(Transport) |
传输层 |
TCP, UDP |
网络层(Network) |
网络层 |
IP, ICMP, ARP, RARP, AKP, UUCP |
数据链路层(Data Link) |
数据链路层 |
FDDI, Ethernet, Arpanet, PDN, SLIP, PPP |
物理层(Physical) |
IEEE 802.1A, IEEE 802.2到IEEE 802.11 |
http三次握手
第一次握手: 客户端告诉服务端说要创建连接
第二次握手:服务端收到请求后知道有客户来了,然后就为客户端开启tcp socket的端口,开启后返回给客户端,返回的ack是客户端第一次请求过来的seq+1
第三次握手: 客户端收到服务端的返回后知道被服务端答应了,这里请求里带上ack=y+1与服务端建立连接
URI URL URN
URI = Universal Resource Identifier 统一资源标志符,它包含URL和URN。
URI采用一种特定语法标识一个资源的字符串。所标识的资源可能是服务器上的一个文件。不过,也可能是一个邮件地址、新闻消息、图书、人名、Internet主机或者任何其它内容。
URL = Universal Resource Locator 统一资源定位符
URL唯一地标识一个资源在Internet上的位置。不管用什么方法表示,只要能定位一个资源,就叫URL。
URN = Universal Resource Name 统一资源名称
URN它命名资源但不指定如何定位资源,比如:只告诉你一个人的姓名,不告诉你这个人在哪。
三者区别
-
- URI 指的是一个资源
- URL 用地址定位一个资源;
- URN 用名称定位一个资源。
举个例子:去寻找一个具体的人(URI);如果用地址:XX省XX市XX区...XX单元XX室的主人 就是URL;如果用身份证号+名字去找就是URN(身份证号+名字 无法确认资源的地址) 。
http报文(好文推荐:https://blog.csdn.net/shouwang666666/article/details/70232053)
请求报文
HTTP请求报文由请求行(request line)、请求头部(header)、空行和请求数据4个部分组成。
请求行包括 请求方法(如:GET、POST等)和http版本组成
请求头由一系列的键值对组成,如User-Agent:xxxx、Content-Type:xxxx等
请求体则是传输的数据
一个简单的请求报文如下:
POST /user HTTP/1.1 //请求行 Host: www.user.com Content-Type: application/x-www-form-urlencoded Connection: Keep-Alive User-agent: Mozilla/5.0. //以上是首部行 (此处必须有一空行) //空行分割header和请求内容 name=world 请求体
响应报文
响应报文由状态行、响应头、空行和响应体组成
-
- 状态行由三部分组成:服务器HTTP协议版本,响应状态码,状态码的文本描述,如:HTTP/1.1 200 OK
常见的状态码:
200 OK:请求已正常处理。
301 Moved Permanently:资源的uri已更新,永久性重定向
302 Found:资源的URI已临时定位到其他位置了,临时性重定向
304 Not Modified:自从上次请求后,请求的网页未修改过。服务器返回此响应时,不会返回网页内容。
400 Bad Request:服务器端无法理解客户端发送的请求,请求报文中可能存在语法错误。
401 Unauthorized:未授权,该状态码表示发送的请求需要有通过HTTP认证(BASIC认证,DIGEST认证)的认证信息。
403 Forbidden:不允许访问那个资源。该状态码表明对请求资源的访问被服务器拒绝了。(权限,未授权IP等)
404 Not Found:服务器上没有请求的资源。路径错误等。
500 Internal Server Error:貌似内部资源出故障了。该状态码表明服务器端在执行请求时发生了错误。也有可能是web应用存在bug或某些临时故障。
503 Service Unavailable:抱歉,我现在正在忙着。该状态码表明服务器暂时处于超负载或正在停机维护,现在无法处理请求
-
- 响应头由一系列的键值对组成,如Connection:keep-alive、Content-Type:xxxx等
- 响应体就是传输的数据
CORS跨域请求(好文推荐:http://www.ruanyifeng.com/blog/2016/04/cors.html)
需要浏览器和服务器同时支持,目前几乎所有的浏览器都集成了fetch api,服务器需要设置接口允许跨域
对CORS来说,分为简单请求和非简单请求,简单请求就直接发送CORS请求,非简单请求需要发送预检请求并得到肯定答复后才能发送正式的请求。
表现形式就是:简单请求在浏览器的network中就只能看到一个请求,非简单请求在浏览器的network中能看到两个请求
CORS请求的本质:当发现跨域请求是,给请求头添加Access-Control-Allow-Origin
Cache-Control(好文推荐:https://zhuanlan.zhihu.com/p/79042406)
Cache-Control 是一个 HTTP 协议中关于缓存的响应头,它由一些能够允许你定义一个响应资源应该何时、如何被缓存以及缓存多长时间的指令组成。
Cache-Control no-cache
no-chache
使用 ETag 响应头来告知客户端(浏览器、代理服务器)这个资源首先需要被检查是否在服务端修改过
,在这之前不能被复用。这个意味着no-cache
将会和服务器进行一次通讯,确保返回的资源没有修改过,如果没有修改过,才没有必要下载这个资源。反之,则需要重新下载。
Cache-Control no-store
no-store
在处理资源不能被缓存和复用的逻辑的时候与 no-cache
类似,然而,他们之间有一个重要的区别。no-store
要求资源每次都被请求并且下载下来。当在处理隐私信息(private information)的时候,这是一个重要的特性。
Cache-Control public & private
包含public
指令的响应资源表示允许被任何中间者(可能是代理服务器、类似于 cdn 网络)缓存。这个指令通常不需要在响应头中用到,因为其他指令已经表明了响应资源是否可以被缓存(例如:max-age
)。
private
指令表示响应资源仅仅只能被获取它的浏览器端缓存。它不允许任何中间者(intermediate)缓存响应的资源。
Cache-Control max-age
这个指令告诉浏览器端或者中间者,响应资源能够在它被请求之后的多长时间以内被复用。例如,max-age
等于 3600 意味着响应资源能够在接下来的 60 分钟以内被复用,而不需要从服务端重新获取。(可以发现,max-age
的单位是秒)
Cache-Control s-maxage
s-maxage
与上文提到的max-age
类似,这里的“s”代表共享,并且,这个指令一般用于代理服务器。这个指令会覆盖max-age
和expires
响应头。
Cache-Control no-transform
中间代理有时会改变图片以及文件的格式,从而达到提高性能的效果。no-transform
指令告诉中间代理不要改变资源的格式。
Last-Modified和Etag
- Last-Modified 上次修改时间,配合If-Modified-Since或者If-Unmodifiled-Since使用,对比上次修改时间已验证资源是否需要更新
- Etage 数据签名,配合If-Match或者If-Non-Match使用,对比资源的签名判断是否使用缓存
- 设置了etag、last-modified后,浏览器在第二次发起请求后就会把if-none-match和if-modified-since带上
ETag是HTTP1.1中才加入的一个属性,用来帮助服务器控制Web端的缓存验证。它的原理是这样的,当浏览器请求服务器的某项资源(A)时, 服务器根据A算出一个哈希值(3f80f-1b6-3e1cb03b)并通过 ETag 返回给浏览器,浏览器把"3f80f-1b6-3e1cb03b" 和 A 同时缓存在本地,当下次再次向服务器请求A时,会通过类似 If-None-Match: "3f80f-1b6-3e1cb03b" 的请求头把ETag发送给服务器,服务器再次计算A的哈希值并和浏览器返回的值做比较,如果发现A发生了变化就把A返回给浏览器(200),如果发现A没有变化就给浏览器返回一个304未修改。这样通过控制浏览器端的缓存,可以节省服务器的带宽,因为服务器不需要每次都把全量数据返回给客户端。
注:HTTP中并没有指定如何生成ETag,哈希是比较理想的选择。
通常情况下,ETag更类似于资源指纹(fingerprints),如果资源发生变化了就会生成一个新的指纹,这样可以快速的比较资源的变化。在服务器端实现中,很多情况下并不会用哈希来计算ETag,这会严重浪费服务器端资源,很多网站默认是禁用ETag的。有些情况下,可以把ETag退化,比如通过资源的版本或者修改时间来生成ETag。
如果通过资源修改时间来生成ETag,那么效果和HTTP协议里面的另外一个控制属性(Last-Modified)就雷同了,使用 Last-Modified 的问题在于它的精度在秒(s)的级别,比较适合不太敏感的静态资源。
cookie和session
cookie:
服务端返回数据时通过set-Cookie设置到浏览器内,浏览器保存cookie后,在同域的访问内下次请求会自动带上
cookie可以以数组的形式设置多个:'Set-Cookie':['id=123','abc=456']
cookie可以设置过期时间:'Set-Cookie':['id=123;max-age=10','abc=456']
max-age:有效期多长
expires:到期的具体时间
如未设置过期时间,则浏览器关闭后消失
设置HttpOnly后,浏览器无法通过document.cookie读取该cookie
domain:访问域设定
cookie只能一个域内访问
a.com不能访问b.com下的cookie
domain设置可以让a.test.com能够访问test.com下的cookie
不能跨域设置cookie,只能一级设置二级,使所有一级域名下的二级域名都可以访问该一级域名下的cookie
session:
Session是另一种记录客户状态的机制,不同的是Cookie保存在客户端浏览器中,而Session保存在服务器上。客户端浏览器访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上。这就是Session。客户端浏览器再次访问时只需要从该Session中查找该客户的状态就可以了。
http长连接
- 从 HTTP/1.1起,默认使用长连接,用以保持连接特性。使用长连接的HTTP协议,会在响应头有加入这行代码:Connection:keep-alive
- 在使用长连接的情况下,当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的 TCP连接不会关闭,如果客户端再次访问这个服务器上的网页,会继续使用这一条已经建立的连接。Keep-Alive不会永久保持连接,它有一个保持时间,可以在不同的服务器软件中设定这个时间。
- 长链接可以设置timeout
- 同个tcp内是有先后顺序的
- chrome浏览器可以并发6个tcp
- Connection:keep-alive(长)、close(短)
- http2:信道复用 ,同域下,tcp并发发送http请求
CSP:Content-Security-Policy(内容安全策略)
'Content-Security-Policy':'default-src http: https:' //只加载外链资源 'Content-Security-Policy':'default-src \'self\'' //只加载同域下的外链资源(包括图片等所有资源) 'Content-Security-Policy':'script-src \'self\'' //只加载同域下的script资源 'Content-Security-Policy':'default-src \'self\' https://cdn.bootcss.com' //只加载同域或指定域名下的外链资源 'Content-Security-Policy':'default-src \'self\'; form-action \'self\'' //只加载同域下的外链资源,form表单只能提交到本地 'Content-Security-Policy':'acript-src \'self\'; form-action \'self\'; report-uri /report' //将不符合条件的资源请求提交报告给服务器/report地址下(资源请求被block掉) 'Content-Security-Policy-Report-Only':'acript-src \'self\'; form-action \'self\'; report-uri /report' //将不符合条件的资源提交报告给服务器/report地址下(资源请求不被block掉)