• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • 跨域资源共享 CORS

    前后端分离,难免会碰到跨域问题。跨域资源共享(CORS)是一种浏览器机制,可以对位于给定域之外的资源进行受控访问。它扩展并增加了同源策略(SOP)的灵活性。但是,如果网站的 CORS 策略配置和实施不当,它也会为基于跨域的攻击提供可能性。

    同源策略

    浏览器同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。

    "同源"指的是"三个相同"。

    • protocol 协议相同
    • host 域名相同
    • port 端口相同

    举例来说,http://www.example.com/dir/page.html这个网址

    • 协议http://
    • 域名www.example.com
    • 端口80(默认端口可以省略)


    跨域资源共享

    CORS (Cross-Origin Resource Sharing,跨域资源共享)是一个协议,它由一系列传输的 HTTP头组成,这些 HTTP头决定浏览器是否阻止前端 JavaScript 代码获取跨域请求的响应。同源安全策略,默认阻止“跨域”获取资源。但是 CORS 给了web服务器这样的权限,即服务器可以选择,允许跨域请求访问到它们的资源。

    出于安全性,浏览器限制脚本内发起的跨源 HTTP 请求。例如,XMLHttpRequestFetch API 遵循同源策略。这意味着使用这些 API 的 Web 应用程序只能从加载应用程序的同一个域请求 HTTP 资源。除非被请求的服务器的响应报文(HTTP Response header)包含了正确 CORS 响应头。

    跨源资源共享(Cross-Origin Resource Sharing,简写 CORS)。一个正在运行的 web 应用,通过HTTP Response header来告诉浏览器,来自不同源的访问请求,是被允许的。是一种基于 HTTP 头的机制,该机制通过允许服务器标示除了它自己以外的其它 origin(域,协议和端口),使得浏览器允许这些 origin,访问加载自己的资源。跨源资源共享,还通过一种机制来检查服务器是否会允许要发送的真实请求,该机制通过浏览器发起一个到服务器托管的跨源资源的"预检"请求。在预检中,浏览器发送的头中标示有 HTTP 方法和真实请求中会用到的头。

    跨源域资源共享(CORS)机制允许 Web 应用服务器进行跨源访问控制,从而使跨源数据传输得以安全进行。现代浏览器支持在 API 容器中(例如 XMLHttpRequest 或 Fetch)使用 CORS,以降低跨源 HTTP 请求所带来的风险。


    这份 CORS 允许在下列场景中使用跨站点 HTTP 请求:

    • XMLHttpRequestFetch API发起的跨源 HTTP 请求。
    • Web 字体(CSS 中通过@font-face 使用跨源字体资源),因此,网站就可以发布 TrueType 字体资源,并只允许已授权网站进行跨站调用。
    • WebGL 贴图。使用 drawImage 将 Images/video 画面绘制到 canvas。
    • 来自图像的 CSS 图形


    CORS 头

    跨源资源共享标准(CORS)新增了一组 HTTP 首部字段,允许服务器声明哪些源站通过浏览器有权限访问哪些资源。另外,规范要求,对那些可能对服务器数据产生副作用的 HTTP 请求方法(特别是 GET 以外的 HTTP 请求,或者搭配某些 MIME 类型的 POST 请求),浏览器必须首先使用 OPTIONS 方法发起一个预检请求(preflight request),从而获知服务端是否允许该跨源请求。服务器确认允许之后,才发起实际的 HTTP 请求。在预检请求的返回中,服务器端也可以通知客户端,是否需要携带身份凭证(包括 Cookies 和 HTTP认证相关数据)。

    CORS 请求失败会产生错误,但是为了安全,在 JavaScript 代码层面是无法获知到底具体是哪里出了问题。你只能查看浏览器的控制台以得知具体是哪里出现了错误。

    • Access-Control-Allow-Origin:指示请求的资源能共享给哪些域。
    • Access-Control-Allow-Credentials:指示当请求的凭证标记为 true 时,是否响应该请求。
    • Access-Control-Allow-Headers:用在对预请求的响应中,指示实际的请求中可以使用哪些 HTTP 头。
    • Access-Control-Allow-Methods:指定对预请求的响应中,哪些 HTTP 方法允许访问请求的资源。
    • Access-Control-Expose-Headers:指示哪些 HTTP 头的名称能在响应中列出。
    • Access-Control-Max-Age:指示预请求的结果能被缓存多久。
    • Access-Control-Request-Headers:用于发起一个预请求,告知服务器正式请求会使用那些 HTTP 头。
    • Access-Control-Request-Method:用于发起一个预请求,告知服务器正式请求会使用哪一种 HTTP 请求方法。
    • Origin:指示获取资源的请求是从什么域发起的。


    CORS 请求

    根据跨域资源共享机制的工作原理,可以划分为简单请求非简单请求。主要应用于三个场景:简单请求、预检请求、认证请求


    简单请求

    某些请求不会触发 CORS 预检请求。本文称这样的请求为“简单请求”,请注意,该术语并不属于 Fetch CORS 规范,而是XMLHttpRequest CORS 规范。若请求满足所有下述条件,则该请求可视为“简单请求”,有五个方面:

    1. 请求方法,使用下列方法之一:GETPOSTHEAD
    2. 请求 header 中,仅包含【允许人为设置值】的首部字段。也就是说,不得人为设置下列集合之外的其他首部字段:AcceptAccept-LanguageContent-LanguageContent-Type(需要注意额外的限制)。若浏览器使用的代理设置,浏览器的代理自动设置的首部字段(例如 Connection,User-Agent),是被允许的,也属于简单请求。另外,不能包含【自定义的首部字段】。比如:header 请求中,包含个人自定义首部字段X-PINGOTHER,此请求会被试为【非简单请求】。
    3. Content-Type的值仅限于下列三者之一:text/plainmultipart/form-dataapplication/x-www-form-urlencoded
    4. 请求中的任意XMLHttpRequest对象均没有注册任何事件监听器;XMLHttpRequest 对象可以使用 XMLHttpRequest.upload 属性访问。
    5. 请求中没有使用ReadableStream对象。


    Safari 浏览器

    浏览器Safari,广泛应用于 iPhone,iPad 和 Mac 设备。苹果公司推出的新版浏览器:Safari Technology Preview。另外,WebKit NightlySafari遗弃版本,适用于 windows 上的版本,现在已经放弃了。曾经有过短暂的存在。


    浏览器Safari Technology PreviewWebKit Nightly,为首部字段AcceptAccept-LanguageContent-Language有额外的限制。如果这些首部字段的值并不符合这些限制,这两款浏览器将这些请求视为非简单请求,也会发送预请求。参考内容如下:

    这两个版本的 Safari 浏览器的这些限制,不是CORS的标准规范,不属于CORS规范的一部分。


    预检请求

    凡是不能同时满足【简单请求】五个条件的,都被视为【非简单请求】,在发送正式请求之前,会首先使用OPTIONS方法发起一个预检请求到服务器,以获知服务器是否允许该实际请求。【预检请求】的使用,可以避免跨域请求对服务器的用户数据产生未预期的影响。

    比如:网络请求 Axios 软件工具,与服务器交互信息,使用JSON方式的时候,其 header 头部请求是Content-Type:application/json。所以属于【非简单请求】,会发送【预检请求】。另外,当 header 头部请求信息中,携带 token 进行 http 验证的时候,其携带字段Authorization,此字段虽然不是个人自定义的,但却在【允许人为设置值】的首部字段范围之外,所以也是属于【非简单请求】,而发送【预检请求】。


    举例:一个需要执行预检请求的 HTTP 请求。

    const xhr = new XMLHttpRequest();
    xhr.open('POST', 'https://bar.other/resources/post-here/');
    xhr.setRequestHeader('X-PINGOTHER', 'pingpong');
    xhr.setRequestHeader('Content-Type', 'application/xml');
    xhr.onreadystatechange = handler;
    xhr.send('<person><name>Arun</name></person>');
    

    上面的代码使用 POST 请求发送一个 XML 文档,该请求包含了一个自定义的请求首部字段(X-PINGOTHER: pingpong)。另外,该请求的 Content-Typeapplication/xml。因此,该请求需要首先发起【预检请求】。

    Content-Type 请求类型列表,参考


    认证请求

    一般而言,对于跨源 XMLHttpRequest 或 Fetch 请求,浏览器不会发送身份凭证信息。服务器的响应头设置为:Access-Control-Allow-Credentials: false。此时,Access-Control-Allow-Origin,可以设置为 ,来允许任何的源请求。当然也可以设置为某个指定的域请求。例如:Access-Control-Allow-Origin: https://foo.example,限制只有 https://foo.example 可以跨域访问而获得资源。

    为了 web 应用安全,CORS 交互的时候,需要增加身份认证,让 XMLHttpRequest(或 Fetch)携带身份凭证,携带 Cookies 或者 HTTP 认证相关数据(比如 token、TLS 客户端证书等)。那么此时,服务器的响应头设置为:Access-Control-Allow-Credentials: true,而 Access-Control-Allow-Origin,不能设置为 *,必须指定限制访问的域名,例如:Access-Control-Allow-Origin: https://foo.example

    在响应附带身份凭证的请求时:

    • 服务器不能将 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

    对于附带身份凭证的请求(通常是 Cookie 或者 token),服务器不得设置 Access-Control-Allow-Origin:* 。否则,请求将会失败。另外,响应首部中也携带了 Set-Cookie 字段,尝试对 Cookie 进行修改。如果操作失败,将会抛出异常。

    例如,https://foo.example 的某脚本向 https://bar.other 发起一个GET 请求,并设置 Cookies:

    withCredentials = true;
        invocation.onreadystatechange = handler;
        invocation.send();
      }
    }
    

    将 XMLHttpRequest 的 withCredentials 标志设置为 true,从而向服务器发送 Cookies。这是一个简单 GET 请求,所以浏览器不会对其发起“预检请求”。此时服务器的响应头设置为:Access-Control-Allow-Credentials: true,如果服务器端的响应中未设置Access-Control-Allow-Credentials: true,浏览器将不会把响应内容返回给请求的发送者。则响应内容不会返回给请求的发起者。


    HTTP 响应首部字段


    Access-Control-Allow-Origin

    响应首部Access-Control-Allow-Origin字段,指定了该响应的资源是否被允许与给定的 origin 共享。


    语法

    Access-Control-Allow-Origin: *
    Access-Control-Allow-Origin: <origin>
    
    • *:对于不需具备身份凭证的请求,服务器会以*作为通配符,从而允许所有域都具有访问资源的权限。
    • <origin>:指定了允许访问该资源的外域 URI。


    例子

    例如,下面的字段值将允许来自 https://mozilla.org 的请求:

    Access-Control-Allow-Origin: https://mozilla.org
    Vary: Origin
    

    如果服务端指定了具体的域名而非*,那么响应首部中的 Vary 字段的值必须包含 Origin。这将告诉客户端:服务器对不同的源站返回不同的内容。



    Vary

    Vary 是一个 HTTP 响应头部信息,它决定了对于未来的一个请求头,应该用一个缓存的回复(response),还是向源服务器请求一个新的回复。它被服务器用来表明在 content negotiation algorithm(内容协商算法)中选择一个资源代表的时候应该使用哪些头部信息(headers)。

    在响应状态码为 304 Not Modified 的响应中,也要设置 Vary 首部,而且要与相应的 200 OK 响应设置得一模一样。


    语法

    Vary: *
    Vary: <header-name>,<header-name>, ...
    
    • *:所有的请求都被视为唯一并且非缓存的,使用 Cache-Control: no-store,来实现则更适用,这样用于说明不存储该对象更加清晰。
    • <header-name>:逗号分隔的一系列 http 头部名称,用于确定缓存是否可用。

    版本:RFC 7231, section 7.1.4: Vary


    例子

    动态服务。哪种情况下使用 Vary:对于User-Agent 头部信息,例如你提供给移动端的内容是不同的,可用防止你客户端误使用了用于桌面端的缓存。

    Vary: User-Agent
    


    指示源服务器可能使用了请求的 accept-encoding,并接受 accept-language 作为选择此响应内容时的确定因素。

    Vary: accept-encoding, accept-language
    

    源服务器可能会发送两个不同的字段列表目的:

    • 通知缓存收件人不得使用此响应满足后面的请求,除非后面的请求具有相同的所列字段的值作为原始请求。换句话说,Vary扩展缓存键需要将新请求与存储的缓存项匹配。
    • 通知用户代理收件人此响应受内容协商和表示可能会在后续请求中发送,如果在列出的标题字段中提供了其他参数。


    例如,201(已创建)响应中的 ETag 标头字段传递新创建资源的实体标记表示,以便在以后的条件请求中使用防止“丢失更新”问题

     Vary: ETag, Last-Modified
    



    Access-Control-Expose-Headers

    响应首部Access-Control-Expose-Headers列出了哪些首部可以作为响应的一部分暴露给外部。

    默认情况下,只有七种 simple response headers (简单响应首部)可以暴露给外部:Cache-ControlContent-LanguageContent-LengthContent-TypeExpiresLast-ModifiedPragma。如果想要让客户端可以访问到其他的首部信息,可以将它们在Access-Control-Expose-Headers里面列出来。


    语法

    Access-Control-Expose-Headers: <header-name>,<header-name>, ...
    

    <header-name>:包含 0 个或多个除 simple response headers (简单响应首部)之外的首部名称列表,可以暴露给外部,供页面资源使用。


    例子

    想要暴露一个非简单响应首部,可以这样指定:

    Access-Control-Expose-Headers: Content-Length
    

    想要额外暴露自定义的首部,例如 X-Kuma-Revision,可以指定多个,用逗号隔开:

    Access-Control-Expose-Headers: Content-Length, X-Kuma-Revision
    


    前端

    在跨源访问时,XMLHttpRequest 对象的getResponseHeader()方法只能拿到一些最基本的响应头,Cache-ControlContent-LanguageContent-TypeExpiresLast-ModifiedPragma,如果要访问其他头,则需要服务器设置本响应头。Access-Control-Expose-Headers头让服务器把允许浏览器访问的头放入白名单,例如:

    Access-Control-Expose-Headers: X-My-Custom-Header, X-Another-Custom-Header
    

    这样浏览器就能够通过getResponseHeader()访问 X-My-Custom-Header 和 X-Another-Custom-Header 响应头了。



    Access-Control-Allow-Credentials

    响应首部Access-Control-Allow-Credentials,表示是否可以将对身份认证的请求,是否返回内容给页面。true则可以,其他值均不可以。Access-Control-Allow-Credentials头指定了当浏览器的 credentials 设置为true时,是否允许浏览器读取 response 的内容。

    当用于preflight request(预检请求)中,它指定了实际的请求是否可以使用 credentials。当作为对预检请求的响应的一部分时,这能表示是否真正的请求可以使用 credentials。请注意:简单 GET 请求不会被预检;若一个对资源的请求带了credentials,如果这个响应头没有随资源返回,响应就会被浏览器忽视,不会返回到 web 内容。

    身份认证的资格证书(Credentials)可以是cookies,authorization headersTLS client certificates

    对于cookie许可。服务器的响应头Access-Control-Allow-Credentials:true。前端XMLHttpRequest.withCredentials或 Fetch API中的Request()构造器中的credentials选项设置为true,才能使带 cookie 的请求成功。

    对于token许可。服务器的响应头Access-Control-Allow-Credentials:true。后端应用程序为 passport,前端为 Axios,XMLHttpRequest,请求需要设置Authorizationheaders:{'Authorization':'Bearer xxxxxxx'}

    此响应首部,只是对携带身份认证的许可,而做出有效响应。并不验证身份认证信息的真伪。需要 web 应用程序,自己去验证。比如 cookie 携带了 web 应用的账号密码信息,有 web 应用自己去识别其真伪。再比如携带的是 token 信息,需要有 web 应用程序,自己去验证 token 有效性。若验证为无效,有 web 应用程序自身来返回错误信息。


    语法

    Access-Control-Allow-Credentials: true | false
    

    true:这个头的唯一有效值(区分大小写)。如果不需要 credentials,相比将其设为false,请直接忽视这个头。


    例子

    服务器设置,允许 credentials:

    Access-Control-Allow-Credentials: true
    

    前端,使用带credentials的 XHR :

    var xhr = new XMLHttpRequest();
    xhr.open('GET', 'http://example.com/', true);
    xhr.withCredentials = true;
    xhr.send(null);
    

    前端,使用带 credentials 的 Fetch :

    fetch(url, {
      credentials: 'include'
    })
    



    Access-Control-Allow-Methods

    响应首部Access-Control-Allow-Methods,用于preflight request(预检请求)中,其指明了客户端所要访问的资源允许使用的 HTTP 方法或方法列表。


    语法

    Access-Control-Allow-Methods: <method>, <method>, ...
    

    <method>:用逗号隔开的允许使用的HTTP request methods列表。

    HTTP 定义了一组请求方法,以表明要对给定资源执行的操作。指示针对给定资源要执行的期望动作。虽然他们也可以是名词,但这些请求方法有时被称为 HTTP 动词。每一个请求方法都实现了不同的语义,但一些共同的特征由一组共享:例如一个请求方法可以是 safe, idempotent,或 cacheable(en-US)。

    • GET 方法:请求一个指定资源的表示形式,使用GET的请求应该只被用于获取数据。
    • HEAD 方法:请求一个与 GET 请求的响应相同的响应,但没有响应体。
    • POST 方法:用于将实体提交到指定的资源,通常导致在服务器上的状态变化或副作用。
    • PUT 方法:用请求有效载荷替换目标资源的所有当前表示。
    • DELETE 方法:删除指定的资源。
    • CONNECT 方法:建立一个到由目标资源标识的服务器的隧道。
    • OPTIONS 方法:用于描述目标资源的通信选项。
    • TRACE 方法:沿着到目标资源的路径执行一个消息环回测试。
    • PATCH 方法:用于对资源应用部分修改。


    例子

    Access-Control-Allow-Methods: POST, GET, OPTIONS
    



    Access-Control-Allow-Headers

    响应首部Access-Control-Allow-Headers,用于preflight request(预检请求)中,其指明了实际正式请求中允许携带的首部字段。

    简单首部:

    • Accept
    • Accept-Language
    • Content-Language
    • Content-Type 并且值是 application/x-www-form-urlencoded、multipart/form-data 或 text/plain 三种 MIME 类型(不包括参数)

    或者以下客户端头部之一的也可以被认为是简单头部:

    • DPR
    • Downlink(en-US)
    • Save-Data
    • Viewport-Width(en-US)
    • Width(en-US)

    简单首部,始终是被Access-Control-Allow-Headers支持的,不需要在这个首部特意列出。如果请求中含有Access-Control-Request-Headers字段,那么这个首部是必要的。


    语法

    Access-Control-Allow-Headers: *
    Access-Control-Allow-Headers: <header-name>, <header-name>,...
    
    • *:对于没有凭据的请求(没有HTTP cookie 或 HTTP认证信息的请求),值*仅作为特殊的通配符值。在具有凭据的请求中,它被视为没有特殊语义的文字标头名称*。请注意,Authorization 标头不能使用通配符,并且始终需要明确列出。
    • <header-name>:可支持的请求首部名字。请求头会列出所有支持的首部列表,用逗号隔开。简单的首部,不需要特别列出。


    例子

    对服务器的 CORS 请求还支持自定义标头,下例子中自定义表头名为X-Custom-Header

    Access-Control-Allow-Headers: X-Custom-Header
    

    下例展示了支持多个标头。

    Access-Control-Allow-Headers: X-Custom-Header, Upgrade-Insecure-Requests
    

    DELETE 预检请求示例。

    请求头
    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
    



    Access-Control-Max-Age

    响应首部Access-Control-Max-Age,用于preflight request(预检请求)中,指明Access-Control-Allow-MethodsAccess-Control-Allow-Headers提供的信息,可以被缓存多久。在相同 URI 请求preflight request(预检请求),下次不需发送预检请求,直接使用缓存结果。


    语法

    Access-Control-Max-Age: <delta-seconds>
    

    <delta-seconds>:返回结果可以被缓存的最长时间,单位。但不能超越浏览器本身的上限。如果值为-1,表示禁用缓存,则每次请求前都需要使用 OPTIONS 预检请求。

    • 在 Firefox 中,上限是 24 小时(即 86400 秒)。
    • 在 Chromium v76 之前,上限是 10 分钟(即 600 秒)。从 Chromium v76 开始,上限是 2 小时(即 7200 秒)。Chromium 同时规定了一个默认值 5 秒。


    例子

    将预检请求的结果缓存 10 分钟:

    Access-Control-Max-Age: 600 
    



    HTTP 请求首部字段

    本节列出了可用于发起跨源请求的首部字段。请注意,这些首部字段无须手动设置。当开发者使用 XMLHttpRequest 对象发起跨源请求时,它们已经被设置就绪。


    Origin

    请求首部Origin,表明预检请求或实际请求的源站。指示了请求来自于哪个域(站点)。该字段仅指示服务器名称,并不包含任何路径信息。该首部用于 CORS 请求或者 POST 请求。除了不包含路径信息,该字段与 Referer 首部字段相似。

    浏览器会将Origin请求头添加到所有跨域的请求中,除 GET 或 HEAD 请求外的同源请求。如果在 no-cors 模式下发出跨源 GET 或 HEAD 请求,则不会添加Origin


    语法

    Origin: ""
    Origin: <origin>
    
    • 空值:

      有时候将该字段的值置空是有用的,例如,资源由一个 data URL 指定。

    • <origin>:参数的值为源站 URI。它不包含任何路径信息,只是服务器名称。格式:<scheme>://<host>[:<port>]

    注意,在所有访问控制请求(Access-Control-Request-*)中,Origin 首部字段总是被发送。


    例子

    Origin: https://developer.mozilla.org
    



    Access-Control-Request-Method

    请求首部Access-Control-Request-Method,出现于preflight request(预检请求)中,用于通知服务器在真正的请求中会采用哪种 HTTP 方法。因为预检请求所使用的方法总是 OPTIONS ,与实际请求所使用的方法不一样,所以这个请求头是必要的。


    语法

    Access-Control-Request-Method: <method>
    

    <method>:一种 HTTP请求方法,例如 GET、POST 或 DELETE。


    例子

    Access-Control-Request-Method: POST
    



    Access-Control-Request-Headers

    请求首部Access-Control-Request-Headers,出现于preflight request(预检请求)中,用于通知服务器在真正的请求中会采用哪些请求头。


    语法

    Access-Control-Request-Headers:  <header-name>, <header-name>,...
    

    <header-name>,在实际请求中将要包含的一系列 HTTP 头,以逗号分隔。


    例子

    Access-Control-Request-Headers: X-PINGOTHER, Content-Type
    




    http 状态返回代码

    1xx (临时响应)表示临时响应并需要请求者继续执行操作的状态代码。
    代码含义说明
    100Continue请求者应当继续提出请求。服务器返回此代码表示已收到请求的第一部分,正在等待其余部分。
    101切换协议请求者已要求服务器切换协议,服务器已确认并准备切换。


    2xx (成功)表示成功处理了请求的状态代码。
    代码含义说明
    200成功服务器已成功处理了请求。通常,这表示服务器提供了请求的网页。
    201已创建请求成功并且服务器创建了新的资源。
    202已接受服务器已接受请求,但尚未处理。
    203非授权信息服务器已成功处理了请求,但返回的信息可能来自另一来源。
    204无内容服务器成功处理了请求,但没有返回任何内容。
    205重置内容服务器成功处理了请求,但没有返回任何内容。
    206部分内容服务器成功处理了部分 GET 请求。


    3xx (重定向)表示要完成请求,需要进一步操作。通常,这些状态代码用来重定向。
    代码含义说明
    300多种选择针对请求,服务器可执行多种操作。服务器可根据请求者(user agent)选择一项操作,或提供操作列表供请求者选择。
    301永久移动请求的网页已永久移动到新位置。服务器返回此响应(对 GET 或 HEAD 请求的响应)时,会自动将请求者转到新位置。
    302临时移动服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。
    303查看其他位置请求者应当对不同的位置使用单独的 GET 请求来检索响应时,服务器返回此代码。
    304未修改自从上次请求后,请求的网页未修改过。服务器返回此响应时,不会返回网页内容。
    305使用代理请求者只能使用代理访问请求的网页。如果服务器返回此响应,还表示请求者应使用代理。
    307临时重定向服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。


    4xx (请求错误)这些状态代码表示请求可能出错,妨碍了服务器的处理。
    代码含义说明
    400错误请求服务器不理解请求的语法。
    401未授权请求要求身份验证。对于需要登录的网页,服务器可能返回此响应。
    403禁止服务器拒绝请求。
    404未找到服务器找不到请求的网页。
    405方法禁用禁用请求中指定的方法。
    406不接受无法使用请求的内容特性响应请求的网页。
    407需要代理授权此状态代码与 401(未授权)类似,但指定请求者应当授权使用代理。
    408请求超时服务器等候请求时发生超时。
    409冲突服务器在完成请求时发生冲突。服务器必须在响应中包含有关冲突的信息。
    410已删除如果请求的资源已永久删除,服务器就会返回此响应。
    411需要有效长度服务器不接受不含有效内容长度标头字段的请求。
    412未满足前提条件服务器未满足请求者在请求中设置的其中一个前提条件。
    413请求实体过大服务器无法处理请求,因为请求实体过大,超出服务器的处理能力。
    414请求的 URI 过长请求的 URI(通常为网址)过长,服务器无法处理。
    415不支持的媒体类型请求的格式不受请求页面的支持。
    416请求范围不符合要求如果页面无法提供请求的范围,则服务器会返回此状态代码。
    417未满足期望值服务器未满足"期望"请求标头字段的要求。


    5xx (服务器错误)这些状态代码表示服务器在尝试处理请求时发生内部错误。这些错误可能是服务器本身的错误,而不是请求出错。
    代码含义说明
    500服务器内部错误服务器遇到错误,无法完成请求。
    501尚未实施服务器不具备完成请求的功能。例如,服务器无法识别请求方法时可能会返回此代码。
    502错误网关服务器作为网关或代理,从上游服务器收到无效响应。
    503服务不可用服务器目前无法使用(由于超载或停机维护)。通常,这只是暂时状态。
    504网关超时服务器作为网关或代理,但是没有及时从上游服务器收到请求。
    505HTTP 版本不受支持服务器不支持请求中所用的 HTTP 协议版本