HTTP(HyperText Transfer Protocol,超文本传输协议)是互联网上应用最广泛的协议之一,是Web开发的基础。我们每天浏览网页、调用API、上传下载文件,都是在使用HTTP协议。但是,很多人对HTTP协议的了解只停留在"输入网址就能打开网页"的层面,对HTTP协议的工作原理、请求响应结构、状态码、头部字段等了解不多。
作为程序员,深入理解HTTP协议是非常重要的,它能帮助我们更好地开发Web应用,排查网络问题,优化网站性能。今天就来详细讲解HTTP协议,从请求到响应,带大家全面了解这个互联网的基础协议。
HTTP协议简介
1. 什么是HTTP协议: HTTP是超文本传输协议,是一种用于传输超文本(如HTML、图片、视频等)的应用层协议。它基于TCP/IP协议,默认使用80端口(HTTPS默认使用443端口)。HTTP是无状态协议,服务器不会保存客户端的状态,每次请求都是独立的。
2. HTTP协议的历史:
- HTTP/0.9(1991年):最初版本,只有GET方法,没有头部,只能传输HTML
- HTTP/1.0(1996年):增加了POST、HEAD方法,增加了头部字段和状态码,支持传输多种内容类型
- HTTP/1.1(1999年):目前最广泛使用的版本,增加了持久连接、管道化、分块传输、缓存控制、内容协商等
- HTTP/2(2015年):新一代HTTP协议,支持多路复用、头部压缩、服务器推送、二进制帧,性能更好
- HTTP/3(2022年正式标准化):基于QUIC协议,使用UDP替代TCP,解决了TCP队头阻塞问题,性能更好
3. HTTP协议的特点:
- 基于请求-响应模型:客户端发送请求,服务器返回响应
- 无状态:服务器不保存客户端的状态,每次请求都是独立的
- 可扩展:通过头部字段可以扩展功能
- 灵活:可以传输任意类型的数据(通过Content-Type指定)
- 简单快速:协议简单,通信速度快
HTTP请求结构
HTTP请求由三部分组成:请求行、请求头部、请求体。
1. 请求行: 请求行是请求的第一行,包含请求方法、请求URL、HTTP版本。
GET /index.html HTTP/1.1GET:请求方法/index.html:请求URLHTTP/1.1:HTTP版本
2. 请求方法: HTTP定义了多种请求方法,常用的有:
GET:获取资源,请求指定的页面信息,并返回实体主体POST:提交数据,向指定资源提交数据进行处理请求(如提交表单、上传文件)PUT:上传文件,向指定资源位置上传其最新内容DELETE:删除资源,请求服务器删除指定的页面HEAD:获取头部,类似于GET请求,只不过返回的响应中没有具体的内容,用于获取报头OPTIONS:获取选项,返回服务器支持的HTTP方法PATCH:部分更新,对资源进行部分修改
GET和POST的区别:
- GET参数在URL中,POST参数在请求体中
- GET有长度限制(URL长度限制),POST没有长度限制
- GET可以被缓存,POST不能被缓存
- GET可以被收藏为书签,POST不能
- GET只用于获取数据,POST用于提交数据
- GET是幂等的(多次请求结果相同),POST不是幂等的
3. 请求URL: URL(Uniform Resource Locator,统一资源定位符)用于定位互联网上的资源。
https://www.example.com:443/path/to/page?query=value#fragmenthttps:协议www.example.com:域名443:端口/path/to/page:路径?query=value:查询参数#fragment:片段(锚点,不会发送到服务器)
4. 请求头部: 请求头部包含了客户端的环境信息、请求参数等。每行一个头部,格式为字段名: 值。
Host: www.example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Cookie: sessionid=abc123; username=test
Referer: https://www.google.com/常用请求头部:
Host:目标主机和端口User-Agent:客户端信息(浏览器、操作系统等)Accept:客户端能接受的内容类型Accept-Language:客户端能接受的语言Accept-Encoding:客户端能接受的编码(压缩方式)Connection:连接方式(keep-alive持久连接,close关闭连接)Cookie:客户端发送的CookieReferer:请求来源页面Content-Type:请求体的内容类型(POST请求时使用)Content-Length:请求体的长度Authorization:认证信息Cache-Control:缓存控制
5. 请求体: 请求体是请求的数据部分,GET请求通常没有请求体,POST、PUT等请求有请求体。请求体的格式由Content-Type指定。
常见的请求体格式:
application/x-www-form-urlencoded:表单格式,key1=value1&key2=value2multipart/form-data:多部分格式,用于上传文件application/json:JSON格式,{"key1":"value1","key2":"value2"}text/plain:纯文本格式application/xml:XML格式
HTTP响应结构
HTTP响应也由三部分组成:状态行、响应头部、响应体。
1. 状态行: 状态行是响应的第一行,包含HTTP版本、状态码、状态描述。
HTTP/1.1 200 OKHTTP/1.1:HTTP版本200:状态码OK:状态描述
2. 状态码: 状态码是服务器对请求的响应状态,分为5类:
1xx:信息,请求已接收,继续处理2xx:成功,请求已成功被接收、理解、接受3xx:重定向,需要进一步操作以完成请求4xx:客户端错误,请求有语法错误或请求无法实现5xx:服务器错误,服务器未能实现合法的请求
常用状态码:
200 OK:请求成功201 Created:资源创建成功204 No Content:请求成功,但没有返回内容301 Moved Permanently:永久重定向302 Found:临时重定向304 Not Modified:资源未修改,使用缓存400 Bad Request:请求语法错误401 Unauthorized:未授权,需要认证403 Forbidden:禁止访问404 Not Found:资源不存在405 Method Not Allowed:请求方法不允许500 Internal Server Error:服务器内部错误502 Bad Gateway:网关错误503 Service Unavailable:服务不可用504 Gateway Timeout:网关超时
3. 响应头部: 响应头部包含了服务器的信息、响应参数等。
Server: nginx/1.18.0
Date: Tue, 20 Apr 2016 12:00:00 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 1234
Content-Encoding: gzip
Connection: keep-alive
Cache-Control: max-age=3600
ETag: "abc123"
Last-Modified: Mon, 19 Apr 2016 10:00:00 GMT
Set-Cookie: sessionid=xyz789; Path=/; HttpOnly
Location: https://www.example.com/new-page常用响应头部:
Server:服务器信息Date:响应时间Content-Type:响应体的内容类型和编码Content-Length:响应体的长度Content-Encoding:响应体的编码(压缩方式)Connection:连接方式Cache-Control:缓存控制ETag:资源标识,用于缓存验证Last-Modified:资源最后修改时间Set-Cookie:设置CookieLocation:重定向目标URL(3xx状态码时使用)Access-Control-Allow-Origin:跨域允许的源
4. 响应体: 响应体是服务器返回的数据,可以是HTML、JSON、图片、视频等任意类型的数据,格式由Content-Type指定。
HTTP工作原理
1. 一次完整的HTTP请求过程:
- 客户端解析URL,获取域名、端口、路径等
- 客户端通过DNS解析域名,获取服务器IP地址
- 客户端与服务器建立TCP连接(三次握手)
- 客户端发送HTTP请求
- 服务器接收请求,处理请求
- 服务器返回HTTP响应
- 客户端接收响应,解析响应
- 关闭TCP连接(或保持连接用于后续请求)
2. 持久连接: HTTP/1.1默认使用持久连接(Keep-Alive),即一次TCP连接可以处理多个HTTP请求,不需要每次请求都建立新的TCP连接。这样可以减少TCP连接建立和关闭的开销,提高性能。
Connection: keep-alive3. 管道化: HTTP/1.1支持管道化(Pipelining),即客户端可以在一个TCP连接上连续发送多个请求,不需要等待前一个请求的响应。但是服务器必须按请求的顺序返回响应,所以可能会有队头阻塞问题。HTTP/2通过多路复用解决了这个问题。
4. 无状态与Cookie/Session: HTTP是无状态协议,服务器不会保存客户端的状态。但是很多应用需要保存用户状态(如登录状态),这就需要使用Cookie和Session。
- Cookie:服务器通过Set-Cookie头部设置Cookie,浏览器保存Cookie,后续请求自动带上Cookie。Cookie存储在客户端,有大小和数量限制。
- Session:服务器端保存用户状态,通过Cookie中的Session ID关联用户。Session存储在服务器端,没有大小限制,但是需要占用服务器资源。
HTTPS协议
HTTPS(HTTP Secure)是HTTP的安全版本,在HTTP的基础上加入了SSL/TLS加密层,保证数据传输的安全性。
1. HTTPS的作用:
- 加密:数据传输过程中加密,防止被窃听
- 认证:验证服务器身份,防止被冒充
- 完整性:保证数据在传输过程中不被篡改
2. HTTPS的工作原理:
- 客户端与服务器建立TCP连接
- SSL/TLS握手:
- 客户端发送支持的加密算法列表 - 服务器选择加密算法,返回数字证书 - 客户端验证证书,生成预主密钥,用服务器公钥加密后发送 - 双方根据预主密钥生成会话密钥
- 使用会话密钥加密HTTP请求和响应
3. HTTPS vs HTTP:
- HTTPS默认端口443,HTTP默认端口80
- HTTPS需要SSL证书,HTTP不需要
- HTTPS数据加密,HTTP明文传输
- HTTPS性能略低(加密解密开销),但是HTTP/2通常只在HTTPS下使用
- HTTPS更安全,有利于SEO(搜索引擎优先收录HTTPS网站)
HTTP缓存
HTTP缓存是优化网站性能的重要手段,通过缓存可以减少重复请求,加快页面加载速度。
1. 缓存控制头部:
Cache-Control:缓存控制,常用值有:
- max-age=3600:缓存有效期3600秒 - no-cache:可以缓存,但是使用前需要验证 - no-store:不缓存 - public:可以被任何缓存(包括CDN)缓存 - private:只能被客户端缓存
Expires:缓存过期时间(HTTP/1.0的方式,优先级低于Cache-Control)ETag:资源标识,用于缓存验证Last-Modified:资源最后修改时间,用于缓存验证
2. 缓存验证: 当缓存过期后,客户端会向服务器发送验证请求:
If-None-Match:带上之前的ETag值,如果服务器资源未修改,返回304 Not Modified,使用缓存If-Modified-Since:带上之前的Last-Modified时间,如果服务器资源未修改,返回304 Not Modified,使用缓存
3. 强缓存 vs 协商缓存:
- 强缓存:缓存未过期时,直接使用缓存,不向服务器发送请求。由Cache-Control和Expires控制。
- 协商缓存:缓存过期后,向服务器发送验证请求,服务器判断资源是否修改,如果未修改返回304,使用缓存;如果修改返回200和新资源。由ETag/If-None-Match和Last-Modified/If-Modified-Since控制。
跨域与CORS
1. 什么是跨域: 跨域是指浏览器从一个域名的网页去请求另一个域名的资源。浏览器的同源策略限制了跨域请求,只有协议、域名、端口都相同才是同源。
2. CORS(跨域资源共享): CORS是一种跨域解决方案,通过服务器设置响应头部,允许浏览器跨域请求。
常用CORS头部:
Access-Control-Allow-Origin:允许的源,*表示允许所有源Access-Control-Allow-Methods:允许的请求方法Access-Control-Allow-Headers:允许的请求头部Access-Control-Allow-Credentials:是否允许携带CookieAccess-Control-Max-Age:预检请求的缓存时间
3. 简单请求 vs 预检请求:
- 简单请求:GET、HEAD、POST,且Content-Type为application/x-www-form-urlencoded、multipart/form-data、text/plain,直接发送请求
- 预检请求:非简单请求会先发送OPTIONS预检请求,服务器确认允许后再发送实际请求
HTTP性能优化
1. 减少HTTP请求:
- 合并CSS、JS文件
- 使用CSS Sprites合并图片
- 使用内联图片(Base64)
- 懒加载,延迟加载非首屏资源
2. 使用CDN:
- 静态资源使用CDN加速
- CDN节点离用户更近,访问速度更快
- CDN可以缓存静态资源,减轻服务器压力
3. 启用压缩:
- 启用Gzip/Brotli压缩文本资源(HTML、CSS、JS)
- 图片使用合适的格式(WebP、JPEG、PNG)和压缩
- 压缩可以大大减少传输数据量,加快加载速度
4. 合理设置缓存:
- 静态资源设置长期缓存(Cache-Control: max-age=31536000)
- HTML页面设置短期缓存或不缓存
- 使用文件名哈希(如app.abc123.js)实现缓存更新
5. 使用HTTP/2:
- HTTP/2支持多路复用,一个连接可以并行处理多个请求
- HTTP/2支持头部压缩,减少头部传输量
- HTTP/2支持服务器推送,提前推送资源
- HTTP/2性能比HTTP/1.1好很多
6. 优化DNS解析:
- 使用DNS预解析(
<link rel="dns-prefetch" href="//example.com">) - 使用稳定的DNS服务商
- 减少域名数量,减少DNS解析
总结
HTTP协议是Web开发的基础,深入理解HTTP协议对程序员非常重要。本文介绍了HTTP协议的基本概念、请求响应结构、工作原理、HTTPS、缓存、跨域、性能优化等内容。
HTTP协议虽然看起来简单,但是细节很多,需要在实际开发中不断学习和实践。希望这篇文章能帮助大家更好地理解HTTP协议,在开发中更好地使用HTTP,排查网络问题,优化网站性能。
HTTP协议还在不断发展,从HTTP/1.1到HTTP/2再到HTTP/3,性能越来越好,功能越来越强大。作为程序员,我们要持续学习,跟上技术的发展,用好HTTP协议,开发出更好的Web应用。
评论(0)
暂无评论,快来抢沙发~
评论功能仅对会员开放,请先登录
登录