HTTP
一. 概念
网络模型
层级 | 协议 |
---|---|
应用层 | HTTP,SMTP,FTP,DNS |
运输层 | TCP,UDP |
网络层 | IP |
链路层 | |
物理层 |
HTTP 协议
超文本(Hypertext)传输(Transfer)协议(Protocol)
在网络中的 2 台计算机之间传输文字,图片,音频,视频等超文本数据的约定和规范;
包含请求报文和响应报文,报文由起始行,标头,空行,实体组成。
TCP 协议
传输(Transmission)控制(Control)协议(Protocol)
IP 协议
互联网(Internet)协议(Protocol)
DNS
域名(Domain Name)系统(System)
将域名和 IP 地址相互映射的一个分布式数据库系统
二. 报文
报文结构
请求报文 | 响应报文 | |
---|---|---|
起始行(Start Line) | 请求方法 URL HTTP版本 | HTTP版本 状态码 状态码描述 |
标头(Header) | 通用标头 + 实体标头 + 请求标头 | 通用标头 + 实体标头 + 响应标头 |
[空行] | ||
实体(Body) | 请求数据 | 响应数据 |
HTTP版本
- HTTP/0.9
- HTTP/1.0
- HTTP/1.1(主流)
- HTTP/2
- HTTP/3
请求方法
- GET:获取资源
- POST:创建/更新资源(非幂等性)
- PUT:创建/更新资源(幂等性)
- DELETE:删除资源
- HEAD:获取响应头部,用于确认URL的有效性,资源修改日期等
- OPTIONS:获取当前 URL 所支持的请求方法
- TRACE
- CONNECT
TODO
get一般用是携带url参数,post是携带请求体,但是get也可以通过请求体传数据,post也可以通过url参数传数据
状态码
- 2XX:成功状态码
- 200 OK:正常返回
- 201 Created:请求成功并且服务器创建了新的资源
- 202 Accepted:服务器接收请求但尚未处理
- 3XX:重定向
- 301 Moved Permanently:永久重定向(转GET)
- 302 Found:临时重定向(转GET)
- 303 See Other:临时重定向(转GET)
- 304 Not Modified:自从上次请求后未修改过
- 307 Temporary Redirect:临时重定向(方法保持)
- 308 Permanent Redirect:永久重定向(方法保持)
- 4XX:客户端错误
- 400 Bad Request:请求存在错误
- 401 Unauthorized:未授权
- 403 Forbidden:禁止访问
- 404 Not Found:找不到资源
- 5XX:服务器错误
- 500 Internal Server Error:服务端错误
- 503 Service Unavailable:服务器不可用
三. 缓存
缓存控制
字段 | 消息类型 | 描述 |
---|---|---|
Cache-Control | 请求 / 响应 | HTTP/1.1 出的缓存控制字段(Expires,Pragma 是 HTTP/1.0 出的) |
Pragma: no-cache | 请求 / 响应 | 等同 Cache-Control: no-cache |
Expires:Tue, 23 Mar 2021 02:00:29 GMT | 响应 | 缓存过期时间,类似Cache-Control: max-age=60 |
优先级:Pragma > Cache-Control > Expires
Cache-Control 指令
指令解析
指令 | 消息类型 | 描述 |
---|---|---|
no-store | 请求 / 响应 | 不缓存 |
public | 响应 | 缓存位置:浏览器,代理服务器 |
private | 响应 | 缓存位置:浏览器(默认) |
no-cache | 请求 / 响应 | 缓存,但每次使用前都需要验证 |
max-age=[秒] | 请求 / 响应 | 缓存时长,没过期直接使用缓存,过期再验证 |
s-maxage=[秒] | 响应 | 同max-age,作用于代理服务器 |
max-stale=[秒] | 请求 | 在过期时长内,继续使用缓存,超过再验证 |
min-fresh=[秒] | 请求 | 在新鲜时长外,即使没过期也验证 |
指令总结
- 不缓存:no-store
- 缓存:
- 缓存位置
- private
- public
- 验证规则
- 不限时长:默认
- 强缓存:max-age / s-maxage,max-stale,min-fresh
- 协商缓存:no-cache
- 缓存位置
优先级1:no-store > no-cache > max-age
优先级2:请求标头 > 响应标头
实践测试
- no-store 无效
- no-cache 不携带验证字段,相当于获取最新资源,【Ctrl + f5】或【devTools禁用缓存 + f5】自动添加
- max-age 仅max-age=0 有效,访问html文件默认该值
- max-stale 无效
- min-fresh 无效
缓存验证
字段 | 消息类型 | 描述 |
---|---|---|
Etag: w6s2de | 响应 | 资源的摘要标识 |
Last-Modified: Tue, 23 Mar 2021 02:00:29 GMT | 响应 | 资源的最后修改时间 |
If-None-Match: w6s2de | 请求 | 上次请求响应头部的 Etag 值 |
If-Modfied-Since: Tue, 23 Mar 2021 02:00:29 GMT | 请求 | 上次请求响应头部的 Last-Modified 值 |
验证机制
服务器根据请求携带的摘要标志或最后修改时间,
判断资源有无更新(优先级 Etag > Last-Modified),
无更新则返回304,浏览器使用本地缓存
有更新则返回200,新的资源,Etag,Last-Modified
四. 标头
通用头部
# 创建报文时间,采用格林威治标准时间,即比北京时间小8h
Date: Wed, 21 Oct 2015 07:28:00 GMT
# 网络连接方式
Connection:
keep-alive # 持久连接,HTTP/1.1开始默认使用
close # 非持久连接,重新请求需要再建TCP连接
# 持久连接时,连接时间和最大请求次数
Keep-Alive: timeout=5, max=1000
Cache-Control: no-cache
Pragma: no-cache
实体头部
# 允许的请求方法
Allow: GET, POST, HEAD
# 服务端实际返回的内容编码,与 Accept-Encoding 呼应
Content-Encoding: gzip
# 服务端实际返回的语言类型,与 Accept-Language 呼应
Content-Language: de-DE, en-CA
# 内容大小(单位:字节)
Content-Length: 3000
# 资源访问的直接链接
Content-Location: /documents/foo.json
# 客户端对响应报文实体执行MD5算法,比较该字段以确定实体是否保持完整
Content-MD5: e10adc3949ba59abbe56e057f20f883e
# 符合客户端请求的范围
Content-Range: bytes 200-1000/67589
# 实体的 MIME 类型
Content-Type: text/css
请求头部
# MIME类型
Accept: text/css,*/*;q=0.1 # ;q=0.x表示权重,默认1,权重从高到底放置
# 字符编码
Accept-Charset: utf-8, iso-8859-1;q=0.5
# 希望服务端返回的内容编码(压缩算法)
Accept-Encoding: gzip, deflate, br
# 希望服务端返回的语言类型
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6
# 认证信息
Authorization: Basic XX
# 域名
Host: www.baidu.com
# 页面链接
Referer: http://localhost/Test/html/page.html
# 浏览器信息
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0
# 请求目的地
Sec-Fetch-Dest: style # 取值:document,script,style,iframe,image,video...
# 请求模式
Sec-Fetch-Mode: no-cors # 取值:cors 允许跨域,需要服务端设置cors响应头
# no-cors 允许跨域,但不需要服务端设置cors响应头(默认)
# same-origin 同源,不允许跨域
# navigate 页面切换,返回html
# websocket websokcet连接
# 请求源和目标源的关系
Sec-Fetch-Site: cross-site # 取值:cross-site 跨域
# sam-origin 同源
# sam-site 同源或子源
# none 在地址栏或书签直接访问
If-None-Match: w6s2de
if-Modfied-Since: Tue, 23 Mar 2021 02:00:29 GMT
响应头部
# 服务器能处理请求返回 bytes,不能处理返回 none
Accept-Ranges: bytes
# 源服务器在多久前创建的响应(即在代理服务器缓存的时长)
age: 381247
ETag: "606bc1a1-e"
Last-Modified: Tue, 06 Apr 2021 02:04:17 GMT
Expires: Tue, 23 Mar 2021 02:00:29 GMT
# 重定向地址
Location: https://www.baidu.com/
# 服务器信息
Server: openresty/1.19.3.1
# TODO 跨域相关
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: x-requested-with,content-type
Access-Control-Allow-Methods: GET,POST
Access-Control-Allow-Origin: -
Access-Control-Expose-Headers: x-via
五. CORS
CORS:Cross-Origin Resource Sharing(跨域资源共享)
(教程: http://www.ruanyifeng.com/blog/2016/04/cors.html)
简单请求
请求条件
- 请求方法: HEAD,GET,POST
- 头部字段(以内):
- Accept
- Accept-Language
- Content-Language
- Last-Event
- Content-type(application/x-www-form-urlencoded,multipart/form-data,text/plain)
请求流程
- 浏览器直接发出 CORS 请求,在头部增加 Origin 字段(请求来源,如 http://api.bob.com)
- 来源不许可:响应头部不带 Access-Control-Allow-Origin,触发 onerror 事件(状态码可能是200)
- 来源许可:响应头部带以下字段
- Access-Control-Allow-Origin: http://api.bob.com
- Access-Control-Allow-Credentials: true(是否发送cookie,当 true 时服务端的 Allow-Origin 不能为*)
- Access-Control-Expose-Headers: FooBar(可选,指定 getResponseHeader() 可拿到的字段)
非简单请求
请求流程
发送预检的 OPTIONS 类型请求,携带以下字段
- Origin
- Access-Control-Request-Method 正式请求的类型
- Access-Control-Request-Headers 正式请求额外的请求头
预检响应许可,响应头部
Access-Control-Allow-Methods: GET, POST, PUT(服务器支持的所有跨域的方法)
Access-Control-Allow-Headers: X-Custom-Header(服务器支持的所有头信息字段)
Access-Control-Allow-Credentials: true(是否发送cookie)
Access-Control-Max-Age: 1728000(预检有效期)
六. HTTPS 证书
自制证书后,生成机构证书(ca.crt),点击安装到本地,运行 certmgr.msc,打开证书管理器,从“中间证书颁发机构/证书”,拖到“受信任的根证书颁发机构/证书”。
网站证书 xx.crt 和 xx.key 放到 nginx 或 webpack 服务器中进行配置。