• Crossorigin resource sharing JSON with Padding 同源策略 JSONP 为什么form表单提交没有跨域问题,但ajax提交有跨域问题? XMLHttpRequest and the Fetch API follow the sameorigin policy 预检请求(preflight request)


    Access-Control-Allow-Headers

     

    响应首部 Access-Control-Allow-Headers 用于 preflight request (预检请求)中,列出了将会在正式请求的 Access-Control-Request-Headers 字段中出现的首部信息。

    简单首部,如 simple headersAcceptAccept-LanguageContent-LanguageContent-Type (只限于解析后的值为 application/x-www-form-urlencoded、multipart/form-data 或 text/plain 三种MIME类型(不包括参数)),它们始终是被支持的,不需要在这个首部特意列出。

    如果请求中含有 Access-Control-Request-Headers 字段,那么这个首部是必要的。

    Header type Response header
    Forbidden header name no

    语法

    Access-Control-Allow-Headers: <header-name>[, <header-name>]*
    Access-Control-Allow-Headers: *

    指令

    <header-name>
    可支持的请求首部名字。请求头会列出所有支持的首部列表,用逗号隔开。

    注意以下这些特定的首部是一直允许的:AcceptAccept-LanguageContent-LanguageContent-Type (但只在其值属于 MIME 类型 application/x-www-form-urlencodedmultipart/form-data 或 text/plain中的一种时)。这些被称作simple headers,你无需特意声明它们。

    * (wildcard)

    对于没有凭据的请求(没有HTTP cookie或HTTP认证信息的请求),值“ *”仅作为特殊的通配符值。 在具有凭据的请求中,它被视为没有特殊语义的文字标头名称“ *”。 请注意,Authorization标头不能使用通配符,并且始终需要明确列出。

    示例

     

    自定义的请求头

    下面是 Access-Control-Allow-Headers 标头的一个示例。 它表明,除了CORS安全清单列出的请求标头外,对服务器的CORS请求还支持名为X-Custom-Header的自定义标头。

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

    Multiple headers

    此示例展示了支持多个标头时的 Access-Control-Allow-Headers 。

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

    Example preflight request

    让我们看一个涉及Access-Control-Allow-Headers的预检请求示例。 

    Request

    First, the request.  The preflight request is an OPTIONS request which includes some combination of the three preflight request headers: Access-Control-Request-MethodAccess-Control-Request-Headers, and Origin, such as:

    OPTIONS /resource/foo
    Access-Control-Request-Method: DELETE
    Access-Control-Request-Headers: origin, x-requested-with
    Origin: https://foo.bar.org

    Response

    If the server allows CORS requests to use the DELETE method, it responds with an Access-Control-Allow-Methods response header, which lists DELETE along with the other methods it supports:

    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

    If the requested method isn't supported, the server will respond with an error.

    Access-Control-Request-Headers - HTTP | MDN https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Access-Control-Request-Headers

    Access-Control-Request-Headers

     

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

    报头类型 Request header
    Forbidden header name yes

    语法

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

    指令

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

    示例

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

     

     从127.0.0.1请求123.123.123.123

    跨域请求已经实现;

    如何在跨域请求时,携带Cookie

    跨域请求传递Cookie问题 - nuccch - 博客园 https://www.cnblogs.com/nuccch/p/7875189.html

    Access-Control-Allow-Credentials - HTTP | MDN https://developer.mozilla.org/en-US/docs/web/http/headers/access-control-allow-credentials

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

    Access-Control-Allow-Credentials 响应头表示是否可以将对请求的响应暴露给页面。返回true则可以,其他值均不可以。

    Credentials可以是 cookies, authorization headers 或 TLS client certificates。

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

    Access-Control-Allow-Credentials 头 工作中与XMLHttpRequest.withCredentials 或Fetch API中的Request() 构造器中的credentials 选项结合使用。Credentials必须在前后端都被配置(即the Access-Control-Allow-Credentials header 和 XHR 或Fetch request中都要配置)才能使带credentials的CORS请求成功。

     
     
     

    调试代码

    <!DOCTYPE html>

    <html lang="en">

    <head>

        <meta charset="UTF-8">

        <title>Title</title>

    </head>

    <body>

    123

    </body>

    </html>

    <script>

        let url = "http://xx/List/dd?Limit=3668&OffSet=0&Z=61014101"

        var xhr = new XMLHttpRequest();

        xhr.open('GET', url, true);

        xhr.onload = function () {

            // Request finished. Do processing here.

            console.log(xhr.responseText)

        };

        xhr.send(null);

    </script>

    func _FilterFunc2(in ghttp.Handler) ghttp.Handler {
    return ghttp.HandlerFunc(func(w ghttp.ResponseWriter, req *ghttp.Request) {
    // access-control-allow-methods: GET,POST,PUT,DELETE
    w.Header().Set("access-control-allow-methods", "OPTIONS,GET,POST")
    w.Header().Set("access-control-allow-origin", "*")
    if req.Method == ghttp.MethodOptions {
    w.WriteHeader(ghttp.StatusOK)
    return
    }
    in.ServeHTTP(w, req)
    })
    }


    xhr.open('OPTIONS', url, true); // GET

    XMLHttpRequest.send() - Web APIs | MDN https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/send

    https://zh.wikipedia.org/wiki/跨来源资源共享

    跨来源资源共享(CORS)是一份浏览器技术的规范,提供了 Web 服务从不同域传来沙盒脚本的方法,以避开浏览器的同源策略[1],是 JSONP 模式的现代版。与 JSONP 不同,CORS 除了 GET 要求方法以外也支持其他的 HTTP 要求。用 CORS 可以让网页设计师用一般的 XMLHttpRequest,这种方式的错误处理比 JSONP 要来的好。另一方面,JSONP 可以在不支持 CORS 的老旧浏览器上运作。现代的浏览器都支持 CORS[2]

    ajax请求总是不成功?浏览器的同源策略和跨域问题详解-博客-云栖社区-阿里云 https://yq.aliyun.com/articles/27800

    什么是同源

    如果两个页面拥有相同的协议(protocol: http),端口(port: 80),和主机(host: xiaoming.com),那么这两个页面就属于同一个源(origin)。

    解决方案

    这里就不讲多年前的iframe、flash等方式了,只讲几个最常用到的方案

    A.x.com 和 B.x.com 间的跨域

    子域名不同也是会受到跨域限制的。这种问题最简单,只需要将页面声明为更高级的域就可以了。

     

     

    Cross-Origin Resource Sharing (CORS) - HTTP | MDN https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS

     

    Cross-Origin Resource Sharing (CORS) is a mechanism that uses additional HTTP headers to tell a browser to let a web application running at one origin (domain) have permission to access selected resources from a server at a different origin. A web application makes a cross-origin HTTP request when it requests a resource that has a different origin (domain, protocol, and port) than its own origin.

    An example of a cross-origin request: The frontend JavaScript code for a web application served from http://domain-a.com uses XMLHttpRequest to make a request forhttp://api.domain-b.com/data.json.

    For security reasons, browsers restrict cross-origin HTTP requests initiated from within scripts. For example, XMLHttpRequest and the Fetch API follow the same-origin policy. This means that a web application using those APIs can only request HTTP resources from the same origin the application was loaded from, unless the response from the other origin includes the right CORS headers.

    The CORS mechanism supports secure cross-origin requests and data transfers between browsers and web servers. Modern browsers use CORS in an API container such asXMLHttpRequest or Fetch to help mitigate the risks of cross-origin HTTP requests.

    HTTP访问控制(CORS) - HTTP | MDN https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS

    跨域资源共享(CORS) 是一种机制,它使用额外的 HTTP 头来告诉浏览器  让运行在一个 origin (domain) 上的Web应用被准许访问来自不同源服务器上的指定的资源。当一个资源从与该资源本身所在的服务器不同的域或端口请求一个资源时,资源会发起一个跨域 HTTP 请求
     
    比如,站点 http://domain-a.com 的某 HTML 页面通过 <img> 的 src 请求 http://domain-b.com/image.jpg。网络上的许多页面都会加载来自不同域的CSS样式表,图像和脚本等资源。
     
     

    出于安全原因,浏览器限制从脚本内发起的跨源HTTP请求。 例如,XMLHttpRequest和Fetch API遵循同源策略。(For security reasons, browsers restrict cross-origin HTTP requests initiated from within scripts. )

    这意味着使用这些API的Web应用程序只能从加载应用程序的同一个域请求HTTP资源,除非使用CORS头文件。

      (译者注:这段描述不准确,并不一定是浏览器限制了发起跨站请求,也可能是跨站请求可以正常发起,但是返回结果被浏览器拦截了。)

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

    谁应该读这篇文章?

    说实话,每个人。

    更具体地来讲,这篇文章适用于网站管理员、后端和前端开发者。现代浏览器处理跨域资源共享的客户端部分,包括HTTP头和相关策略的执行。但是这一新标准意味着服务器需要处理新的请求头和响应头。对于服务端的支持,开发者可以阅读补充材料 cross-origin sharing from a server perspective (with PHP code snippets) 。

    什么情况下需要 CORS ?

    跨域资源共享标准( cross-origin sharing standard )允许在下列场景中使用跨域 HTTP 请求:

    本文概述了跨域资源共享机制及其所涉及的 HTTP 头。

    功能概述

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

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

    接下来的内容将讨论相关场景,并剖析该机制所涉及的 HTTP 首部字段。

    若干访问控制场景

    这里,我们使用三个场景来解释跨域资源共享机制的工作原理。这些例子都使用 XMLHttpRequest 对象。

    本文中的 JavaScript 代码片段都可以从 http://arunranga.com/examples/access-control/ 获得。另外,使用支持跨域  XMLHttpRequest 的浏览器访问该地址,可以看到代码的实际运行结果。

    关于服务端对跨域资源共享的支持的讨论,请参见这篇文章: Server-Side_Access_Control (CORS)

    简单请求

    某些请求不会触发 CORS 预检请求。本文称这样的请求为“简单请求”,请注意,该术语并不属于 Fetch (其中定义了 CORS)规范。若请求满足所有下述条件,则该请求可视为“简单请求”:

    注意: 这些跨域请求与浏览器发出的其他跨域请求并无二致。如果服务器未返回正确的响应首部,则请求方不会收到任何数据。因此,那些不允许跨域请求的网站无需为这一新的 HTTP 访问控制特性担心。
    注意: WebKit Nightly 和 Safari Technology Preview 为AcceptAccept-Language, 和 Content-Language 首部字段的值添加了额外的限制。如果这些首部字段的值是“非标准”的,WebKit/Safari 就不会将这些请求视为“简单请求”。WebKit/Safari 并没有在文档中列出哪些值是“非标准”的,不过我们可以在这里找到相关讨论:Require preflight for non-standard CORS-safelisted request headers Accept, Accept-Language, and Content-LanguageAllow commas in Accept, Accept-Language, and Content-Language request headers for simple CORS, and Switch to a blacklist model for restricted Accept headers in simple CORS requests。其它浏览器并不支持这些额外的限制,因为它们不属于规范的一部分。

    比如说,假如站点 http://foo.example 的网页应用想要访问 http://bar.other 的资源。http://foo.example 的网页中可能包含类似于下面的 JavaScript 代码:

    var invocation = new XMLHttpRequest();
    var url = 'http://bar.other/resources/public-data/';
       
    function callOtherDomain() {
      if(invocation) {    
        invocation.open('GET', url, true);
        invocation.onreadystatechange = handler;
        invocation.send(); 
      }
    }

    客户端和服务器之间使用 CORS 首部字段来处理跨域权限:

    分别检视请求报文和响应报文:

    GET /resources/public-data/ HTTP/1.1
    Host: bar.other
    User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3pre) Gecko/20081130 Minefield/3.1b3pre
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
    Accept-Language: en-us,en;q=0.5
    Accept-Encoding: gzip,deflate
    Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
    Connection: keep-alive
    Referer: http://foo.example/examples/access-control/simpleXSInvocation.html
    Origin: http://foo.example
    
    
    HTTP/1.1 200 OK
    Date: Mon, 01 Dec 2008 00:23:53 GMT
    Server: Apache/2.0.61 
    Access-Control-Allow-Origin: *
    Keep-Alive: timeout=2, max=100
    Connection: Keep-Alive
    Transfer-Encoding: chunked
    Content-Type: application/xml
    
    [XML Data]

    第 1~10 行是请求首部。第10行 的请求首部字段 Origin 表明该请求来源于 http://foo.exmaple

    第 13~22 行是来自于 http://bar.other 的服务端响应。响应中携带了响应首部字段 Access-Control-Allow-Origin(第 16 行)。使用 Origin 和 Access-Control-Allow-Origin 就能完成最简单的访问控制。本例中,服务端返回的 Access-Control-Allow-Origin: * 表明,该资源可以被任意外域访问。如果服务端仅允许来自 http://foo.example 的访问,该首部字段的内容如下:

    Access-Control-Allow-Origin: http://foo.example

    现在,除了 http://foo.example,其它外域均不能访问该资源(该策略由请求首部中的 ORIGIN 字段定义,见第10行)。Access-Control-Allow-Origin 应当为 * 或者包含由 Origin 首部字段所指明的域名。

    预检请求

    与前述简单请求不同,“需预检的请求”要求必须首先使用 OPTIONS   方法发起一个预检请求到服务器,以获知服务器是否允许该实际请求。"预检请求“的使用,可以避免跨域请求对服务器的用户数据产生未预期的影响。

    当请求满足下述任一条件时,即应首先发送预检请求:

    注意: WebKit Nightly 和 Safari Technology Preview 为AcceptAccept-Language, 和 Content-Language 首部字段的值添加了额外的限制。如果这些首部字段的值是“非标准”的,WebKit/Safari 就不会将这些请求视为“简单请求”。WebKit/Safari 并没有在文档中列出哪些值是“非标准”的,不过我们可以在这里找到相关讨论:Require preflight for non-standard CORS-safelisted request headers Accept, Accept-Language, and Content-LanguageAllow commas in Accept, Accept-Language, and Content-Language request headers for simple CORS, and Switch to a blacklist model for restricted Accept headers in simple CORS requests。其它浏览器并不支持这些额外的限制,因为它们不属于规范的一部分。

    如下是一个需要执行预检请求的 HTTP 请求:

    var invocation = new XMLHttpRequest();
    var url = 'http://bar.other/resources/post-here/';
    var body = '<?xml version="1.0"?><person><name>Arun</name></person>';
        
    function callOtherDomain(){
      if(invocation)
        {
          invocation.open('POST', url, true);
          invocation.setRequestHeader('X-PINGOTHER', 'pingpong');
          invocation.setRequestHeader('Content-Type', 'application/xml');
          invocation.onreadystatechange = handler;
          invocation.send(body); 
        }
    }
    
    ......

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

     1.OPTIONS /resources/post-here/ HTTP/1.1
     2.Host: bar.other
     3.User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3pre) Gecko/20081130 Minefield/3.1b3pre
     4.Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
     5.Accept-Language: en-us,en;q=0.5
     6.Accept-Encoding: gzip,deflate
     7.Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
     8.Connection: keep-alive
     9.Origin: http://foo.example
    10.Access-Control-Request-Method: POST
    11.Access-Control-Request-Headers: X-PINGOTHER, Content-Type
    12.
    13.
    14.HTTP/1.1 200 OK
    15.Date: Mon, 01 Dec 2008 01:15:39 GMT
    16.Server: Apache/2.0.61 (Unix)
    17.Access-Control-Allow-Origin: http://foo.example
    18.Access-Control-Allow-Methods: POST, GET, OPTIONS
    19.Access-Control-Allow-Headers: X-PINGOTHER, Content-Type
    20.Access-Control-Max-Age: 86400
    21.Vary: Accept-Encoding, Origin
    22.Content-Encoding: gzip
    23.Content-Length: 0
    24.Keep-Alive: timeout=2, max=100
    25.Connection: Keep-Alive
    26.Content-Type: text/plain

    预检请求完成之后,发送实际请求:

    POST /resources/post-here/ HTTP/1.1
    Host: bar.other
    User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3pre) Gecko/20081130 Minefield/3.1b3pre
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
    Accept-Language: en-us,en;q=0.5
    Accept-Encoding: gzip,deflate
    Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
    Connection: keep-alive
    X-PINGOTHER: pingpong
    Content-Type: text/xml; charset=UTF-8
    Referer: http://foo.example/examples/preflightInvocation.html
    Content-Length: 55
    Origin: http://foo.example
    Pragma: no-cache
    Cache-Control: no-cache
    
    <?xml version="1.0"?><person><name>Arun</name></person>
    
    
    HTTP/1.1 200 OK
    Date: Mon, 01 Dec 2008 01:15:40 GMT
    Server: Apache/2.0.61 (Unix)
    Access-Control-Allow-Origin: http://foo.example
    Vary: Accept-Encoding, Origin
    Content-Encoding: gzip
    Content-Length: 235
    Keep-Alive: timeout=2, max=99
    Connection: Keep-Alive
    Content-Type: text/plain
    
    [Some GZIP'd payload]

    浏览器检测到,从 JavaScript 中发起的请求需要被预检。从上面的报文中,我们看到,第 1~12 行发送了一个使用 OPTIONS 方法的“预检请求”。 OPTIONS 是 HTTP/1.1 协议中定义的方法,用以从服务器获取更多信息。该方法不会对服务器资源产生影响。 预检请求中同时携带了下面两个首部字段:

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

    首部字段 Access-Control-Request-Method 告知服务器,实际请求将使用 POST 方法。首部字段 Access-Control-Request-Headers 告知服务器,实际请求将携带两个自定义请求首部字段:X-PINGOTHER 与 Content-Type。服务器据此决定,该实际请求是否被允许。

    第14~26 行为预检请求的响应,表明服务器将接受后续的实际请求。重点看第 17~20 行:

    Access-Control-Allow-Origin: http://foo.example
    Access-Control-Allow-Methods: POST, GET, OPTIONS
    Access-Control-Allow-Headers: X-PINGOTHER, Content-Type
    Access-Control-Max-Age: 86400

    首部字段 Access-Control-Allow-Methods 表明服务器允许客户端使用 POST, GET 和 OPTIONS 方法发起请求。该字段与 HTTP/1.1 Allow: response header 类似,但仅限于在需要访问控制的场景中使用。

    首部字段 Access-Control-Allow-Headers 表明服务器允许请求中携带字段 X-PINGOTHER Content-Type Access-Control-Allow-Methods 一样,Access-Control-Allow-Headers 的值为逗号分割的列表。

    最后,首部字段 Access-Control-Max-Age 表明该响应的有效时间为 86400 秒,也就是 24 小时。在有效时间内,浏览器无须为同一请求再次发起预检请求。请注意,浏览器自身维护了一个最大有效时间,如果该首部字段的值超过了最大有效时间,将不会生效。

    预检请求与重定向

    大多数浏览器不支持针对于预检请求的重定向。如果一个预检请求发生了重定向,浏览器将报告错误:

    The request was redirected to 'https://example.com/foo', which is disallowed for cross-origin requests that require preflight

    Request requires preflight, which is disallowed to follow cross-origin redirect

    CORS 最初要求该行为,不过在后续的修订中废弃了这一要求

    在浏览器的实现跟上规范之前,有两种方式规避上述报错行为:

    • 在服务端去掉对预检请求的重定向;
    • 将实际请求变成一个简单请求。

    如果上面两种方式难以做到,我们仍有其他办法:

    不过,如果请求是由于存在 Authorization 字段而引发了预检请求,则这一方法将无法使用。这种情况只能由服务端进行更改。

    附带身份凭证的请求

    Fetch 与 CORS 的一个有趣的特性是,可以基于  HTTP cookies 和 HTTP 认证信息发送身份凭证。一般而言,对于跨域 XMLHttpRequest 或 Fetch 请求,浏览器不会发送身份凭证信息。如果要发送凭证信息,需要设置 XMLHttpRequest 的某个特殊标志位。

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

    var invocation = new XMLHttpRequest();
    var url = 'http://bar.other/resources/credentialed-content/';
        
    function callOtherDomain(){
      if(invocation) {
        invocation.open('GET', url, true);
        invocation.withCredentials = true;
        invocation.onreadystatechange = handler;
        invocation.send(); 
      }
    }

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

    客户端与服务器端交互示例如下:

    GET /resources/access-control-with-credentials/ HTTP/1.1
    Host: bar.other
    User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3pre) Gecko/20081130 Minefield/3.1b3pre
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
    Accept-Language: en-us,en;q=0.5
    Accept-Encoding: gzip,deflate
    Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
    Connection: keep-alive
    Referer: http://foo.example/examples/credential.html
    Origin: http://foo.example
    Cookie: pageAccess=2
    
    
    HTTP/1.1 200 OK
    Date: Mon, 01 Dec 2008 01:34:52 GMT
    Server: Apache/2.0.61 (Unix) PHP/4.4.7 mod_ssl/2.0.61 OpenSSL/0.9.7e mod_fastcgi/2.4.2 DAV/2 SVN/1.4.2
    X-Powered-By: PHP/5.2.6
    Access-Control-Allow-Origin: http://foo.example
    Access-Control-Allow-Credentials: true
    Cache-Control: no-cache
    Pragma: no-cache
    Set-Cookie: pageAccess=3; expires=Wed, 31-Dec-2008 01:34:53 GMT
    Vary: Accept-Encoding, Origin
    Content-Encoding: gzip
    Content-Length: 106
    Keep-Alive: timeout=2, max=100
    Connection: Keep-Alive
    Content-Type: text/plain
    
    
    [text/plain payload]

    即使第 11 行指定了 Cookie 的相关信息,但是,如果 bar.other 的响应中缺失 Access-Control-Allow-Credentials: true(第 19 行),则响应内容不会返回给请求的发起者。

    附带身份凭证的请求与通配符

    对于附带身份凭证的请求,服务器不得设置 Access-Control-Allow-Origin 的值为“*”。

    这是因为请求的首部中携带了 Cookie 信息,如果 Access-Control-Allow-Origin 的值为“*”,请求将会失败。而将 Access-Control-Allow-Origin 的值设置为 http://foo.example,则请求将成功执行。

    另外,响应首部中也携带了 Set-Cookie 字段,尝试对 Cookie 进行修改。如果操作失败,将会抛出异常。

    HTTP 响应首部字段

    本节列出了规范所定义的响应首部字段。上一小节中,我们已经看到了这些首部字段在实际场景中是如何工作的。

    Access-Control-Allow-Origin

    响应首部中可以携带一个 Access-Control-Allow-Origin 字段,其语法如下:

    Access-Control-Allow-Origin: <origin> | *

    其中,origin 参数的值指定了允许访问该资源的外域 URI。对于不需要携带身份凭证的请求,服务器可以指定该字段的值为通配符,表示允许来自所有域的请求。

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

    Access-Control-Allow-Origin: http://mozilla.com

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

    Access-Control-Expose-Headers

    译者注:在跨域访问时,XMLHttpRequest对象的getResponseHeader()方法只能拿到一些最基本的响应头,Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma,如果要访问其他头,则需要服务器设置本响应头。

    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-Max-Age

    Access-Control-Max-Age 头指定了preflight请求的结果能够被缓存多久,请参考本文在前面提到的preflight例子。

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

    delta-seconds 参数表示preflight请求的结果在多少秒内有效。

    Access-Control-Allow-Credentials

    Access-Control-Allow-Credentials 头指定了当浏览器的credentials设置为true时是否允许浏览器读取response的内容。当用在对preflight预检测请求的响应中时,它指定了实际的请求是否可以使用credentials。请注意:简单 GET 请求不会被预检;如果对此类请求的响应中不包含该字段,这个响应将被忽略掉,并且浏览器也不会将相应内容返回给网页。

    Access-Control-Allow-Credentials: true

    上文已经讨论了附带身份凭证的请求

    Access-Control-Allow-Methods

    Access-Control-Allow-Methods 首部字段用于预检请求的响应。其指明了实际请求所允许使用的 HTTP 方法。

    Access-Control-Allow-Methods: <method>[, <method>]*

    相关示例见这里

    Access-Control-Allow-Headers

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

    Access-Control-Allow-Headers: <field-name>[, <field-name>]*

    HTTP 请求首部字段

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

    Origin

    Origin 首部字段表明预检请求或实际请求的源站。

    Origin: <origin>

    origin 参数的值为源站 URI。它不包含任何路径信息,只是服务器名称。

    Note: 有时候将该字段的值设置为空字符串是有用的,例如,当源站是一个 data URL 时。

    注意,不管是否为跨域请求,ORIGIN 字段总是被发送。

    Access-Control-Request-Method

    Access-Control-Request-Method 首部字段用于预检请求。其作用是,将实际请求所使用的 HTTP 方法告诉服务器。

    Access-Control-Request-Method: <method>

    相关示例见这里

    Access-Control-Request-Headers

    Access-Control-Request-Headers 首部字段用于预检请求。其作用是,将实际请求所携带的首部字段告诉服务器。

    Access-Control-Request-Headers: <field-name>[, <field-name>]*

    相关示例见这里

    规范

    SpecificationStatusComment
    Fetch
    CORS
    Living Standard New definition; supplants CORS specification.
    Unknown Unknown Initial definition.

    Timing-Allow-Origin - HTTP | MDN https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Timing-Allow-Origin

    Request URL:https://www.taobao.com/
    Request Method:GET
    Status Code:304 Not Modified
    Remote Address:103.43.210.87:443
    Referrer Policy:no-referrer-when-downgrade
    Response Headers
    view source
    Age:235
    Ali-Swift-Global-Savetime:1556273957
    Cache-Control:max-age=60, s-maxage=300
    Connection:keep-alive
    Content-MD5:JwYINnxaNwKeR+K+3u+bIw==
    Content-Type:text/html; charset=utf-8
    Date:Sat, 27 Apr 2019 16:23:41 GMT
    EagleId:672bd26415563822219225626e
    ETag:W/"2b18-16a5901c260"
    Server:Tengine
    Strict-Transport-Security:max-age=31536000
    Timing-Allow-Origin:*
    Vary:Ali-Detector-Type
    Via:cache13.l2cn241[0,200-0,H], cache13.l2cn241[1,0], cache7.cn175[0,304-0,H], cache6.cn175[0,0]
    X-Cache:HIT TCP_IMS_HIT dirn:-2:-2
    X-Snapshot-Age:1
    

      

    应头Timing-Allow-Origin用于指定特定站点,以允许其访问Resource Timing API提供的相关信息,否则这些信息会由于跨源限制将被报告为零

    Header type Response header
    Forbidden header name no

    语法

    Timing-Allow-Origin: *
    Timing-Allow-Origin: <origin>[, <origin>]*
    

    指令

    *
    服务器可以以“*”作为通配符,从而允许所有域都具有访问定时信息的权限。
    <origin>
    指定一个可以访问资源的URI。你也可以通过逗号隔开,指定多个URI。

    示例

    如需允许任何资源都可以看到的计时(timing)信息,你可以如此设置:

    Timing-Allow-Origin: *

    如需允许https://developer.mozilla.org查看你的计时信息,你可以设置:

    Timing-Allow-Origin: https://developer.mozilla.org

    Resource Timing API - Web APIs | MDN https://developer.mozilla.org/en-US/docs/Web/API/Resource_Timing_API

    The Resource Timing interfaces enable retrieving and analyzing detailed network timing data regarding the loading of an application's resource(s). An application can use the timing metrics to determine, for example, the length of time it takes to load a specific resource, such as an XMLHttpRequest, <SVG>, image, or script.

    The interface's properties create a resource loading timeline with high-resolution timestamps for network events such as redirect start and end times, DNS lookup start and end times, request start, response start and end times, etc. The interface also includes other properties that provide data about the size of the fetched resource as well as the type of resource that initiated the fetch.

    This document provides an overview of the Resource Timing interfaces. For more details about the interfaces including examples see each interface's reference page, Using the Resource Timing API, and the references in the See also section. For a graphical representation of the resource timing processing model see the resource timing phases figure.

    The PerformanceResourceTiming interface extends the PerformanceEntry for performance entries which have an entryType of "resource".

    High-resolution time stamps

    Several of the Resource Timing properties return high-resolution timestamps. These timestamps have a DOMHighResTimeStamp type and as its name implies, they represent a high-resolution point in time. This type is a double and its value is a discrete point in time or the difference in time between two discrete points in time.

    The unit of DOMHighResTimeStamp is milliseconds and should be accurate to 5 µs (microseconds). However, If the browser is unable to provide a time value accurate to 5 µs (because, for example, due to hardware or software constraints), the browser can represent a the value as a time in milliseconds accurate to a millisecond.

    Resource loading timestamps

    An application can get timestamps for the various stages used to load a resource. The first property in the processing model is startTime which returns the timestamp immediately before the resource loading process begins. The fetchStart timestamps follows and redirect processing (if applicable) and preceeds DNS lookup. The next stages are connectStart and connectEnd which are the timestamps immediately before and after connecting to the server, respectively. The last three timestamps are, in order: requestStart - the timestamp before the browser starts requesting the resource from the server; responseStart - the timestamp after the browser receives the first byte of the response from the server; and responseEnd - the timestamp after the browser receives the last byte of the resource. If the resource is loaded via a secure connection a secureConnectionStart timestamp will be available between the connection start and end events.

    When CORS is in effect, many of these values are returned as zero unless the server's access policy permits these values to be shared. This requires the server providing the resource to send the Timing-Allow-Origin HTTP response header with a value specifying the origin or origins which are allowed to get the restricted timestamp values.

    The properties which are returned as 0 by default when loading a resource from a domain other than the one of the web page itself: redirectStart, redirectEnd, domainLookupStart, domainLookupEnd, connectStart, connectEnd, secureConnectionStart, requestStart, and responseStart.

    The PerformanceResourceTiming interface also includes several network timing properties. The redirectStart and redirectEnd properties return timestamps for redirect start and end times, respectively. Likewise, the The domainLookupStart and domainLookupEndproperties return timestamps for DNS lookup start and end times, respectively.

    This would be a nice place to have a diagram showing the relationships between these segments of the resource loading time.

    Resource size

    The PerformanceResourceTiming interface has three properties that can be used to obtain size data about a resource. The transferSize property returns the size (in octets) of the fetched resource including the response header fields plus the response payload body.

    The encodedBodySize property returns the size (in octets) received from the fetch (HTTP or cache), of the payload body, before removing any applied content-codings. decodedBodySizereturns the size (in octets) received from the fetch (HTTP or cache) of the message body, after removing any applied content-codings.

    Other properties

    The nextHopProtocol property returns the network protocol used to fetch the resource.

    The initiatorType property returns the type of resource that initiated the performance entry such as "css" for a CSS resource, "xmlhttprequest" for an XMLHttpRequest and "img" for an image (such as a JPEG).

    If the current context is a worker, the workerStart property can be used to obtain a DOMHighResTimeStamp when the worker was started.

    Methods

    The Resource Timing API includes two methods that extend the Performance interface. The clearResourceTimings() method removes all "resource" type performance entries from the browser's resource performance entry buffer. The setResourceTimingBufferSize()method sets the resource performance entry buffer size to the specified number of resource performance entries.

    The PerformanceResourceTiming interface's toJSON() method returns a JSON serialization of a "resource" type performance entry.

    Implementation status

    As shown in the PerformanceResourceTiming interface's Browser Compatibility table, most of these interfaces are broadly implemented by desktop browsers. However, note that some properties have little to no implementation so see each property's "Browser compatibility" section for more specific interoperability data.

    To test your browser's support for these interfaces, run the perf-api-support application.

    See Also

    九种跨域方式实现原理(完整版) · Issue #55 · ljianshu/Blog https://github.com/ljianshu/Blog/issues/55

    借助服务端代理来转发请求

    <!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>Title</title></head><body>123</body></html><script>    let url = "http://xx/List/dd?Limit=3668&OffSet=0&Z=61014101"    var xhr = new XMLHttpRequest();    xhr.open('GET', url, true);    xhr.onload = function () {        // Request finished. Do processing here.        console.log(xhr.responseText)    };    xhr.send(null);</script>

  • 相关阅读:
    二重循环
    汇编中的大小写转换
    编译出错:must be index or base register
    [bx]和loop指令
    poj1012约瑟夫
    fenshijin
    poj3050
    抹蛋糕
    poj1190
    uuu
  • 原文地址:https://www.cnblogs.com/rsapaper/p/5868009.html
Copyright © 2020-2023  润新知