HTTP是超文本传输协议的缩写是互联网上应用最广泛的协议我们每天上网浏览网页发请求收响应用的都是HTTP协议但是很多人对HTTP协议的理解只是停留在表面知道GETPOST知道一些状态码但是对HTTP协议的完整结构请求方法头部状态码缓存HTTPS等等了解不深。

其实深入理解HTTP协议对Web开发非常重要能帮我们更好地开发调试优化Web应用我做Web开发很多年了每天都在和HTTP打交道也踩了很多坑总结了很多经验今天就来详细讲解一下HTTP协议。

一、HTTP协议基础

HTTP是HyperText Transfer Protocol的缩写中文叫超文本传输协议它是一个基于TCP/IP的应用层协议用来传输超文本数据比如HTML图片视频等等是万维网的基础。

HTTP协议的特点:

  1. 简单快速: HTTP协议简单客户端向服务器请求服务时只需传送请求方法和路径等等简单快速。
  2. 灵活: HTTP允许传输任意类型的数据对象通过Content-Type标记数据类型。
  3. 无连接: HTTP是无连接的每次连接只处理一个请求服务器处理完客户端的请求收到客户端的应答后就断开连接节省传输时间。(HTTP/1.1之后支持长连接Keep-Alive)
  4. 无状态: HTTP是无状态的协议对于事务处理没有记忆能力也就是说服务器不会记住客户端的状态每次请求都是独立的缺少状态意味着如果后续处理需要前面的信息就必须重传这样可能导致每次连接传送的数据量增大但是也让服务器的实现更简单资源占用更少。

HTTP协议的版本主要有:

  • HTTP/1.0:最早的版本每次请求都建立新的连接。
  • HTTP/1.1:目前最广泛使用的版本支持长连接管道等等性能更好。
  • HTTP/2:新版本支持多路复用头部压缩服务器推送等等性能更好越来越多的网站在使用。
  • HTTP/3:最新版本基于QUIC协议性能更好还在普及中。

二、HTTP请求结构

HTTP请求由三部分组成:请求行请求头部请求体。

1. 请求行

请求行由三部分组成:请求方法请求URLHTTP版本用空格分隔。

例如:

GET /index.html HTTP/1.1
  • 请求方法:GET表示请求方法。
  • 请求URL:/index.html表示请求的资源路径。
  • HTTP版本:HTTP/1.1表示HTTP协议版本。

2. 请求方法

HTTP定义了多种请求方法常用的有:

  • GET: 请求获取资源最常用的方法参数放在URL里有长度限制会被缓存书签等等。
  • POST: 向服务器提交数据比如提交表单上传文件等等参数放在请求体里没有长度限制不会被缓存。
  • PUT: 向服务器上传文件或者更新资源是幂等的多次调用结果一样。
  • DELETE: 删除指定的资源。
  • HEAD: 和GET类似但是只返回响应头不返回响应体用来获取资源的元信息比如文件大小最后修改时间等等。
  • OPTIONS: 获取服务器支持的请求方法以及CORS相关的信息跨域的时候会先发OPTIONS预检请求。
  • PATCH: 对资源进行部分更新。

GET和POST的区别是面试常考的问题主要区别:

  1. GET参数在URL里POST参数在请求体里。
  2. GET有长度限制POST没有长度限制。
  3. GET会被缓存POST不会被缓存。
  4. GET能被收藏为书签POST不能。
  5. GET是幂等的POST不是幂等的。
  6. GET只用于获取数据POST用于提交数据。

3. 请求头部

请求头部由多组键值对组成每行一个用冒号分隔键和值用来传递一些附加的信息比如客户端类型接受的数据类型编码等等。

常用的请求头:

  • Host: 请求的服务器域名和端口。
  • User-Agent: 客户端的标识比如浏览器类型版本操作系统等等。
  • Accept: 客户端能接受的内容类型比如text/htmlapplication/json等等。
  • Accept-Encoding: 客户端能接受的编码方式比如gzipdeflate等等。
  • Accept-Language: 客户端能接受的语言比如zh-CNen-US等等。
  • Content-Type: 请求体的内容类型比如application/x-www-form-urlencodedmultipart/form-dataapplication/json等等。
  • Content-Length: 请求体的长度。
  • Cookie: 客户端携带的Cookie用来保持会话状态。
  • Referer: 请求来源页面的URL。
  • Authorization: 认证信息比如Token等等。
  • Cache-Control: 缓存控制指令。
  • If-Modified-Since: 缓存相关比较最后修改时间。
  • If-None-Match: 缓存相关比较ETag。

4. 请求体

请求体是请求携带的数据比如POST提交的表单数据JSON数据上传的文件等等GET请求一般没有请求体。

请求体的格式由Content-Type决定常见的格式:

  • application/x-www-form-urlencoded: 表单默认格式数据被编码成键值对用&分隔比如name=张三&age=18。
  • multipart/form-data: 用于上传文件数据被分成多个部分每个部分是一个字段或者文件。
  • application/json: JSON格式现在API接口常用的格式数据是JSON字符串比如{"name":"张三","age":18}。
  • text/xml: XML格式现在用得比较少了。

三、HTTP响应结构

HTTP响应也由三部分组成:状态行响应头部响应体。

1. 状态行

状态行由三部分组成:HTTP版本状态码状态码描述用空格分隔。

例如:

HTTP/1.1 200 OK
  • HTTP版本:HTTP/1.1。
  • 状态码:200。
  • 状态码描述:OK。

2. 状态码

状态码是服务器对请求的响应状态用三位数字表示分为五类:

  • 1xx: 信息服务器收到请求需要请求者继续操作。
  • 2xx: 成功操作被成功接收理解处理。
  • 3xx: 重定向需要进一步操作才能完成请求。
  • 4xx: 客户端错误请求包含语法错误或者无法完成。
  • 5xx: 服务器错误服务器在处理请求的过程中发生了错误。

常用的状态码:

  • 200 OK: 请求成功最常见的成功状态码。
  • 201 Created: 请求成功并且服务器创建了新的资源。
  • 204 No Content: 请求成功但是没有返回内容。
  • 301 Moved Permanently: 永久重定向资源永久移动到新的URL。
  • 302 Found: 临时重定向资源临时移动到新的URL。
  • 304 Not Modified: 资源未修改使用缓存的版本。
  • 400 Bad Request: 请求语法错误服务器无法理解。
  • 401 Unauthorized: 请求需要认证未登录或者Token无效。
  • 403 Forbidden: 服务器拒绝请求没有权限。
  • 404 Not Found: 资源不存在最常见的错误状态码。
  • 405 Method Not Allowed: 请求方法不被允许。
  • 500 Internal Server Error: 服务器内部错误最常见的服务器错误。
  • 502 Bad Gateway: 网关错误服务器作为网关收到了无效的响应。
  • 503 Service Unavailable: 服务不可用服务器过载或者维护。
  • 504 Gateway Timeout: 网关超时服务器作为网关没有及时收到响应。

3. 响应头部

响应头部和请求头部类似也是键值对用来传递响应的附加信息。

常用的响应头:

  • Server: 服务器的软件信息比如NginxApache等等。
  • Date: 响应的时间。
  • Content-Type: 响应体的内容类型比如text/htmlapplication/json等等。
  • Content-Length: 响应体的长度。
  • Content-Encoding: 响应体的编码方式比如gzip。
  • Last-Modified: 资源最后修改时间用于缓存。
  • ETag: 资源的标识用于缓存。
  • Cache-Control: 缓存控制指令。
  • Expires: 缓存过期时间。
  • Set-Cookie: 设置Cookie服务器通过这个头向客户端设置Cookie。
  • Location: 重定向的URL3xx状态码时使用。
  • Access-Control-Allow-Origin: CORS跨域允许的源。
  • X-Powered-By: 服务器使用的技术比如PHPASP.NET等等。

4. 响应体

响应体是服务器返回的数据比如HTMLJSON图片视频等等是我们真正需要的内容。

响应体的格式由Content-Type决定比如text/html就是HTML页面application/json就是JSON数据image/jpeg就是JPEG图片等等。

四、HTTP缓存

HTTP缓存是HTTP协议中非常重要的一部分能大大提高网站的性能减少服务器的压力减少带宽的消耗。

HTTP缓存分为两种:强缓存和协商缓存。

1. 强缓存

强缓存是浏览器直接使用本地缓存不向服务器发请求状态码是200from cache或者from disk cachefrom memory cache。

强缓存通过两个响应头控制:

  • Expires: 缓存过期时间是一个绝对时间比如Expires: Wed, 21 Oct 2017 07:28:00 GMT在这个时间之前浏览器直接用缓存不发请求。缺点是客户端和服务器时间可能不一致。
  • Cache-Control: 缓存控制指令是HTTP/1.1的头比Expires更强大优先级也更高常用的指令:

- max-age:缓存最大有效时间单位秒是相对时间比如Cache-Control: max-age=3600表示缓存1小时。 - no-cache:不使用强缓存需要和服务器协商验证缓存是否有效。 - no-store:不缓存任何内容每次都从服务器获取。 - public:可以被任何缓存缓存包括CDN代理等等。 - private:只能被客户端缓存不能被代理缓存。

如果Cache-Control和Expires同时存在Cache-Control优先级更高。

2. 协商缓存

协商缓存是强缓存过期后浏览器向服务器发请求服务器判断缓存是否还有效如果有效返回304 Not Modified浏览器继续使用缓存如果无效返回200和新的内容。

协商缓存通过两组请求头和响应头控制:

  • Last-Modified / If-Modified-Since:

- 服务器响应时通过Last-Modified告诉浏览器资源最后修改时间。 - 浏览器下次请求时通过If-Modified-Since把这个时间发给服务器。 - 服务器比较这个时间和资源实际最后修改时间如果一样返回304使用缓存如果不一样返回200和新内容。 - 缺点:只能精确到秒如果1秒内修改多次无法识别而且文件内容没变只是修改时间变了也会返回新内容。

  • ETag / If-None-Match:

- 服务器响应时通过ETag告诉浏览器资源的唯一标识一般是文件内容的哈希值。 - 浏览器下次请求时通过If-None-Match把这个ETag发给服务器。 - 服务器比较这个ETag和资源实际ETag如果一样返回304使用缓存如果不一样返回200和新内容。 - 优点:比Last-Modified更精确能识别内容是否真的变化优先级也比Last-Modified高。

如果ETag和Last-Modified同时存在ETag优先级更高。

3. 缓存的流程

浏览器请求资源的缓存流程:

  1. 浏览器先看强缓存是否有效(Cache-ControlExpires)如果有效直接使用缓存不发请求。
  2. 如果强缓存无效浏览器向服务器发请求带上协商缓存的头(If-Modified-SinceIf-None-Match)。
  3. 服务器判断协商缓存是否有效如果有效返回304浏览器使用缓存如果无效返回200和新内容浏览器更新缓存。

合理使用缓存能大大提高网站性能对于不经常变化的静态资源比如图片CSSJS等等可以设置较长的强缓存时间对于经常变化的内容可以用协商缓存或者不缓存。

五、HTTPS

HTTP是明文传输的数据在传输过程中可能被窃听篡改冒充所以对于敏感数据比如登录支付等等需要用HTTPS。

HTTPS是HTTP Secure的缩写是在HTTP的基础上加入了SSL/TLS加密层数据在传输过程中是加密的安全很多。

HTTPS的工作原理:

  1. 客户端向服务器发起HTTPS请求连接443端口。
  2. 服务器返回数字证书证书里包含服务器的公钥证书颁发机构有效期等等。
  3. 客户端验证证书是否合法有效如果合法生成一个随机的对称密钥用服务器的公钥加密发给服务器。
  4. 服务器用自己的私钥解密得到对称密钥。
  5. 之后双方用这个对称密钥加密解密数据进行通信。

HTTPS用了非对称加密来交换对称密钥然后用对称加密来传输数据结合了非对称加密的安全性和对称加密的高效性。

HTTPS的优点:

  • 安全数据加密传输防止窃听篡改冒充。
  • 信任数字证书由权威机构颁发能验证服务器身份。
  • SEO谷歌百度等等搜索引擎都优先收录HTTPS网站。

HTTPS的缺点:

  • 性能SSL/TLS握手需要时间加密解密也需要CPU资源比HTTP慢一些但是现在硬件性能强影响不大。
  • 成本需要购买数字证书不过现在有免费的证书比如Let's Encrypt。

现在越来越多的网站都在使用HTTPS特别是涉及登录支付等等敏感操作的网站必须用HTTPS。

六、写在最后

HTTP协议详解:从请求响应到状态码的完整理解。

HTTP协议是Web开发的基础深入理解HTTP协议对每个Web开发者都非常重要这篇文章讲解了HTTP协议的基础请求结构响应结构状态码缓存HTTPS等等希望能帮大家深入理解HTTP协议。

当然HTTP协议的内容还有很多比如CookieSessionCORS跨域HTTP/2HTTP/3等等以后有机会再详细分享大家也可以自己去深入学习HTTP协议对Web开发会有很大的帮助。

最后用一句话结尾:

"HTTP是万维网的基石深入理解它能让你在Web开发的道路上走得更稳更远。"

祝大家都能深入理解HTTP协议开发顺利!