• JavaScript跨域(3):HTTP access control (CORS)跨域


      网上看了很多博客和文档,感觉还是Mozilla大大写的最简单、最好懂,不过文字很长。。

      原文链接:https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS

      要整篇翻译,我肯定吃不消,当然也没这个必要,下面就提要说一点吧,这个方法还存在兼容性问题,尽管有相应的解决手段,但是觉得用起来不是特别爽。

    Cross-site HTTP requests are HTTP requests for resources from a different domain than the domain of the resource making the request.  For instance, a resource loaded from Domain A (http://domaina.example) such as an HTML web page, makes a request for a resource on Domain B (http://domainb.foo), such as an image, using the img element (http://domainb.foo/image.jpg).  This occurs very commonly on the web today — pages load a number of resources in a cross-site manner, including CSS stylesheets, images and scripts, and other resources.

      跨站点的HTTP请求也就是从一个域名向另一个域名发送请求(POST,GET等),比如,从http://a.com向http://b.com请求一张图片(http://b.com/images.jpg),这种请求或者说这种现象是时有发生的,所以找到一个好方法来处理这类问题也是十分有必要的。

    Mozilla大大说

      如下,我们在http://foo.example向页面http://bar.example发送请求:

    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();  
      } 
    }

      可以看看服务器对浏览器的响应

    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]

      这些都是关于HTTP的一些数据和参数,如果不太明白的话,可以看看这本书《HTTP权威指南》

      前半截是FF3.5发送的文件头请求,后半截是服务器的响应。你应该注意到了我标红的那些字,这个就是本文要讲述的重点。

      在请求之前,我们也可以自己设定一些服务器要响应的内容

    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);  
        } 
      
    ......

      setRequestHeader顾名思义就是设置请求头的一些参数。

      上面说了半天也就是告诉大家一些服务器和客户端相关参数设置和解释,还没太涉及到跨域的东西。

    Cross Domain [跨域]

      这是我放到SAE上的一段代码(http://1.qianduannotes.sinaapp.com/test/ACAO.php

    <?php
        header("Access-Control-Allow-Origin: *");
        //header("Access-Control-Allow-Origin: http://yourURL.com");
        echo "hello world";
    ?>

      如果我没加header("Access-Control-Allow-Origin: *")这句话,你通过ajax或者其他方式来请求这个数据是会报错的,不信就可以试试这个链接http://1.qianduannotes.sinaapp.com/test/ACAO_none.php

      其中的“*”表示所有域都可以访问,如果将Access-Control-Allow-Origin设置为一个特定的URL,那这个文件就只能被特定URL以及他的子域(http://yoururl.com/sub/)访问。

    Compatibility [兼容性]

    Show all versionsIEFirefoxChromeSafariOperaiOS SafariOpera MiniAndroid BrowserBlackberry Browser
                    2.1  
                    2.2  
                3.2   2.3  
                4.0-4.1   3.0  
      8.0   24.0     4.2-4.3   4.0  
      9.0 19.0 25.0 5.1   5.0-5.1   4.1  
    Current 10.0 20.0 26.0 6.0 12.1 6.0 5.0-7.0 4.2 7.0
    Near future   21.0 27.0           10.0
    Farther future   22.0 28.0            

      最明显的就是IE(8、9)的bug,可以通过XDomainRequest来解决。

    // 1. Create XDR object 
    var xdr = new XDomainRequest(); 
    // 2. Open connection with server using GET method
    xdr.open("get", "http://www.contoso.com/xdr.aspx");
    // 3. Send string data to server
    xdr.send();     

      下面附上一个MSDN上的DEMO

    XDomainRequest From MSDN
    <html>
    <script type="text/javascript">
        var xdr;
        function readdata()
        {
            var dRes = document.getElementById('dResponse');
            dRes.innerText = xdr.responseText;
            alert("Content-type: " + xdr.contentType);
            alert("Length: " + xdr.responseText.length);
        }
        
        function err()
        {
            alert("XDR onerror");
        }
        function timeo()
        {
            alert("XDR ontimeout");
        }
        function loadd()
        {
            alert("XDR onload");
            alert("Got: " + xdr.responseText);
        }
        function progres()
        {
            alert("XDR onprogress");
            alert("Got: " + xdr.responseText);
        }
        function stopdata()
        {
            xdr.abort();
        }
        function mytest()
        {
            var url = document.getElementById('tbURL');
            var timeout = document.getElementById('tbTO');
            if (window.XDomainRequest)
            {
                xdr = new XDomainRequest();
                if (xdr)
                {
                    xdr.onerror = err;
                    xdr.ontimeout = timeo;
                    xdr.onprogress = progres;
                    xdr.onload = loadd;
                    xdr.timeout = tbTO.value;
                    xdr.open("get", tbURL.value);
                    xdr.send();
                }
                else
                {
                    alert('Failed to create');
                }
            }
            else
            {
                alert('XDR doesn't exist');
            }
        }
    </script>
    <body>
        <h2>XDomainRequest</h2>
        <input type="text" id="tbURL" value="http://www.contoso.com/xdr.txt" style="300px"><br>
        <input type="text" id="tbTO" value="10000"><br>
        <input type="button" onclick="mytest()" value="Get">&nbsp;&nbsp;&nbsp;
        <input type="button" onclick="stopdata()" value="Stop">&nbsp;&nbsp;&nbsp;
        <input type="button" onclick="readdata()" value="Read">
        <br>
        <div id="dResponse"></div>
    </body>
    </html>

    Reference [参考资料]

      1.Mozilla

      2.MSDN

      3.http://caniuse.com/

      4.屈屈(关闭了页面,链接给忘了,^_^)

  • 相关阅读:
    大数据是否有可能有效配置资源?
    在大数据时代,我们需要数据售货员
    在大数据时代,我们需要数据售货员
    粗糙的贝叶斯转化概率预测模型
    粗糙的贝叶斯转化概率预测模型
    MVC中的ViewData、ViewBag和TempData
    58被微信玩弄,你知道吗?
    你的以太网速度足够快吗?四种更快的速度正在路上&#183;&#183;&#183;&#183;&#183;&#183;
    hibernate预编译SQL语句中的setParameter和setParameterList
    创建单线性链表的不同表示方法和操作
  • 原文地址:https://www.cnblogs.com/hustskyking/p/CDS_access_contorl_allow_origin.html
Copyright © 2020-2023  润新知