Http必须的请求头
- Host:
- HTTP/1.0 不强制要求
<font style="color:rgb(44, 44, 54);">Host</font>头字段,因为在HTTP/1.0中默认假设所有请求都是针对连接建立时的IP地址指向的主机,不过也可能有Web服务器处理HTTP/1.0请求时,会强制判断Host请求头 - 根据HTTP/1.1规范(RFC 2616),
<font style="color:rgb(44, 44, 54);">Host</font>头字段是必需的,如果请求URI中没有包含主机名,则必须提供<font style="color:rgb(44, 44, 54);">Host</font>头字段。这是因为HTTP/1.1请求中的<font style="color:rgb(44, 44, 54);">Host</font>头字段用于指定被请求资源的Internet主机和端口号,这对于确定服务器上的哪个虚拟主机应该处理该请求至关重要,大部分Web服务器在处理HTTP/1.1请求时,一般都会强制要求Host请求头
- HTTP/1.0 不强制要求
- Content-Length:在有请求体的情况下,Content-Length字段是必须的
- Content-Type:在有请求体的情况下,Content-Type是必须的,比如请求体是json,表单等格式
Connection请求头
在HTTP/1.0和HTTP/1.1版本中,Connection头部字段的区别
- HTTP/1.0:
- 默认情况下,HTTP/1.0中的每个请求都建立一个新的TCP连接,并且在发送完响应后会关闭这个连接。
- 在HTTP/1.0中,虽然可以通过在请求头或响应头中设置 Connection: Keep-Alive 来尝试请求持久连接(即复用同一个TCP连接处理多个HTTP请求),但这并不是标准默认行为,需要客户端和服务端都支持并同意。
- HTTP/1.1:
- HTTP/1.1默认开启了持久连接(Keep-Alive),也就是说,除非明确指定了 Connection: close,否则服务器会在处理完一个请求后保持TCP连接打开以等待后续请求。
- 在HTTP/1.1中,Connection头部字段通常用于关闭连接或者与代理服务器协商特定的连接选项。由于默认已启用持久连接,因此通常不需要显式指定 Connection: Keep-Alive。
预检请求
参考文档:https://developer.mozilla.org/zh-CN/docs/Glossary/Preflight_request
预检请求不属于http规范中,是浏览器在进行跨域请求时的一种保护机制,但是依赖于http规范,和http密切相关。这里需要注意预检请求不会在每次跨域请求时都会触发,但是即使没有触发预检请求,不代表可以进行跨域请求,因为即使请求完成了,但是浏览器发现响应头中的信息不支持跨越,浏览器也会拦截掉不会展示给用户
请求内容
预检请求使用Option方法进行请求,会带上相关特殊的请求头,主要是浏览器将请求中包含的Origin,Method,Header等信息在预检请求中发送给服务端,以确认服务器是否支持这些内容,包括以下请求头
- Origin:发起跨域请求所在的域,ip加端口或者域名加端口
- Access-Control-Request-Method:跨域请求的方法,比如get/post
- Access-Control-Request-Headers:跨域请求包含的所有请求头
响应内容
服务器收到Option请求后,根据约定好的策略返回响应,而响应中一般包含这几个响应头,告诉浏览器支持哪些Origin,Method,Header跨越,这些响应头为
- Access-Control-Allow-Origin:告诉浏览器,服务端支持哪些Origin跨越请求
- Access-Control-Allow-Methods:告诉浏览器,服务端支持哪些Method跨越请求
- Access-Control-Allow-Headers:告诉浏览器,服务端支持哪些Header跨越请求
以上响应头必须同时支持才能发起正常发起跨越请求,如果服务器需要允许跨越,三个响应头都需要设置
何时请求
在非简单请求下,会触发预检请求
在部分浏览器定义中,对于 Accept、Accept-Language 和 Content-Language 标头字段的值添加了额外的限制。如果这些标头字段的值是“非标准”的,那么也会认为是非简单请求(该段内容参考”简单请求”文档中的备注部分)
Cookie跨站问题
在跨域的情况下,即使服务端支持跨域(即设置Access-Control-Allow-Origin等请求头),还要考虑到Cookie跨站的问题(集成需要使用到cookie的第三方系统),不解决的话,发送请求到第三方系统时,不会带上第三方系统的cookie
先了解以下Cookie跨站问题,简单来讲就是不同域名(相同顶级域名可以理解为同一个域名,具体取决于Domain属性)下的网站无法共享cookie,也可以理解为不同ip下无法共享cookie,这里是不涉及端口,和平时讨论的跨域是有所区别的,所以第一时间可以考虑代理,因为cookie跨站问题不涉及端口,代理起来比跨域问题要简单很多,或者使用以下方法
要解决cookie跨站的问题,需要在Set-Cookie响应头中加入same-site=none以及secure两个配置(如果是在js代码中设置cookie,也需要加入这两个配置),如下
1 | Set-Cookie: my_cookie=my_value; SameSite=None; Secure; HttpOnly |
SameSite=None和Secure,这是大部分浏览器的规定,而secure代表只能在https中访问,也就代表只有https中可以解决cookie跨站问题(在不代理的情况下,即不经过服务端,单纯靠客户端只有在https中可以解决)
Http缓存
参考文档:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Caching
Http缓存最主要的Header就是Cache-Control(http/1.1)
这里仅介绍一下几种不同的情况,下面提到的缓存验证以及其他具体内容请查看参考文档
- 响应头中设置Cache-Control为no-cache或者max-age=0:表示要先验证再考虑是否继续使用缓存
- 请求头中设置Cache-Control为max-age=0:和上面一样,表示要先验证再考虑是否继续使用缓存
- 请求头中设置Cache-Control为no-cache:表示不验证直接弃用缓存重新获取,浏览器会放弃缓存并重新加载,谷歌浏览器控制台的停用缓存功能用的就是这种方式