1. http是应用层协议,从1990年左右,0.9版本起步,到1993年1.0版本发布, 2000年左右发布1.1,2015年http2发布,还有目前还在草案的http3,现在很多网站还在使用20年前的http1.1,所以我们主要focus 1.1版本。
2. http报文有3部分组成,请求/响应行 请求/响应头部,请求/响应体(body,与头部用一行空行分隔),很多时候它是大头儿子和小头爸爸模样,所以http2.0引入头部压缩,并且采用索引表记录,每次只传递索引,减少请求内容。
3. 常见的头部
Host,它属于请求字段,只能出现在请求头里,它同时也是唯一一个 HTTP/1.1 规范里要求必须出现的字段,也就是说,如果请求头里没有 Host,那这就是一个错误的报文。
User-Agent 是请求字段,只出现在请求头,由于历史原因,比较混乱,且可以篡改。
Date 字段是一个通用字段,但通常出现在响应头里,表示 HTTP 报文创建的时间
Server 字段是响应字段,只能出现在响应头里。它告诉客户端当前正在提供 Web 服务的软件名称和版本号,不是必须的,所以很多严格的网站,返回任意值,避免黑客知道server,因为黑客可能针对某些特定server版本的漏洞而进行攻击。
Cache相关头,1.1 中的(Cache-Control,ETag, if-none-match),1.0中的(Expires,Last-Modified,If-Modified-Since),同时出现时,1.1中的头优先作为缓存资源判断。
Content-Length,它表示报文里 body 的长度,也就是请求头或响应头空行后面数据的长度。服务器看到这个字段,就知道了后续有多少数据需要接收。
Content-Type,是正文的格式, 比如Content-Type: text/html; charset=utf-8
Vary: Accept-Encoding,User-Agent,Accept,响应报文中,这个 Vary 字段表示服务器依据了 Accept-Encoding、User-Agent 和 Accept 这三个头字段,然后决定了发回的响应报文。
- 数据类型表示实体数据的内容是什么,使用的是 MIME type,相关的头字段是 Accept 和 Content-Type;
- 数据编码表示实体数据的压缩方式,相关的头字段是 Accept-Encoding 和 Content-Encoding;
- 语言类型表示实体数据的自然语言,相关的头字段是 Accept-Language 和 Content-Language;
- 字符集表示实体数据的编码方式,相关的头字段是 Accept-Charset 和 Content-Type;
- 客户端需要在请求头里使用 Accept 等头字段与服务器进行“内容协商”,要求服务器返回最合适的数据;
- Accept 等头字段可以用“,”顺序列出多个可能的选项,还可以用“;q=”参数来精确指定权重。
4. 常见的请求方法,除了下面这些标准请求方法外我们可以自己定义,只要server端认可就行
GET:获取资源,可以理解为读取或者下载数据;一般请求体里没有Body,但也可以有,没有限制的。安全且也是幂等的
HEAD:获取资源的元信息;没有body,所以一般响应码是204;安全且也是幂等的
POST:向资源提交数据,相当于写入或上传数据;新的数据,类似与Insert。不安全且也不幂等的
PUT:类似 POST;但它更多的是修改一条已有的数据,类似于Updae。不安全且但是幂等的
DELETE:删除资源;一般不会真正的删除一条数据,而是做标记,不安全不幂等
CONNECT:建立特殊的连接隧道;比较少用。
OPTIONS:列出可对资源实行的方法;CORS跨域时,对非简单请求会额外发一个options请求到server端,获取是否允许跨域的信息。
TRACE:追踪请求 - 响应的传输路径。
5. 响应码/状态码
它是十进制的三位数,分为五类,从 100 到 599;
2××类状态码表示成功,常用的有 200、204、206;
3××类状态码表示重定向,常用的有 301、302、304,307,308;
4××类状态码表示客户端错误,常用的有 400、403、404;
5××类状态码表示服务器错误,常用的有 500、501、502、503。
“200 OK”是最常见的成功状态码,表示一切正常,服务器如客户端所期望的那样返回了处理结果,如果是非 HEAD 请求,通常在响应头后都会有 body 数据。
“204 No Content”是另一个很常见的成功状态码,它的含义与“200 OK”基本相同,但响应头后没有 body 数据。所以对于 Web 服务器来说,正确地区分 200 和 204 是很必要的。
“206 Partial Content”是 HTTP 分块下载或断点续传的基础,在客户端发送“范围请求”、要求获取资源的部分数据时出现,它与 200 一样,也是服务器成功处理了请求,但 body 里的数据不是资源的全部,而是其中的一部分。状态码 206 通常还会伴随着头字段“Content-Range”,表示响应报文里 body 数据的具体范围,供客户端确认,例如“Content-Range: bytes 0-99/2000”,意思是此次获取的是总计 2000 个字节的前 100 个字节。
“301 Moved Permanently”俗称“永久重定向”,含义是此次请求的资源已经不存在了,需要改用改用新的 URI 再次访问。
“302 Found”,曾经的描述短语是“Moved Temporarily”,俗称“临时重定向”,意思是请求的资源还在,但需要暂时用另一个 URI 来访问。
- 301 和 302 都会在响应头里使用字段 Location 指明后续要跳转的 URI,最终的效果很相似,浏览器都会重定向到新的 URI。两者的根本区别在于语义,一个是“永久”,一个是“临时”,所以在场景、用法上差距很大。比如,你的网站升级到了 HTTPS,原来的 HTTP 不打算用了,这就是“永久”的,所以要配置 301 跳转,把所有的 HTTP 流量都切换到 HTTPS。
- 301表示搜索引擎爬取新内容的同时,将旧的网址替换为重定向之后的网址;
- 302表示旧地址的资源仍存在,重定向时临时从A地址跳转到B地址,搜索引擎会抓取新的内容,并继续保存旧的网址。
303, 临时重定向,不准改请求方法
304, 是缓存没有变化,告知浏览器继续使用。
307,临时重定向,于302,303类似,但不允许改请求方法和请求体。
308 永久重定向,于301类似,但不准改请求数据
- 301、308是永久重定向;302、303、307是临时重定向。
- 301、302是http 1.0的内容,303、307、308是http1.1的内容。
- 301和302本来在规范中是不允许重定向时改变请求method的(将POST改为GET),实际许多浏览器实现的时候允许重定向时改变请求method。
- 303的出现是允许重定向时改变请求method。此外303响应禁止被缓存。307、308则不允许重定向时改变请求method。
400 是一个通用的错误码,表示请求报文有错误,但具体是数据格式错误、缺少请求头还是 URI 超长它没有明确说,只是一个笼统的错误。
401, 一般是权限验证不通过等问题。
403 Forbidden,表示server禁止访问这个资源
404 Not Found,资源不存在
407 代理出问题
500 也是一个通用的错误码,服务器究竟发生了什么错误我们是不知道的
503 Service Unavailable 表示服务器当前很忙,暂时无法响应服务,我们上网时有时候遇到的“网络服务正忙,请稍后重试”的提示信息就是状态码 503