>  기사  >  데이터 베이스  >  JavaScript跨域(3):HTTP access control (CORS)跨域

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

WBOY
WBOY원래의
2016-06-07 15:38:251368검색

网上看了很多博客和文档,感觉还是Mozilla大大写的最简单、最好懂,不过文字很长。。 https://developer.mozilla.org/en-US/docs/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发送请求:

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

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

GET /resources/public-data/ HTTP/1.1 
<span>Host: bar.other 
User</span>-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<span> 
Accept</span>-Language: en-us,en;q=0.5<span> 
Accept</span>-<span>Encoding: gzip,deflate 
Accept</span>-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7<span> 
Connection: keep</span>-<span>alive 
Referer: http:</span><span>//</span><span>foo.example/examples/access-control/simpleXSInvocation.html </span>
Origin: http:<span>//</span><span>foo.example </span>
<span>  
  
HTTP</span>/1.1 200 OK 
Date: Mon, 01 Dec 2008 00:23:53<span> GMT 
Server: Apache</span>/2.0.61  
<span>Access-Control-Allow-Origin: *</span><span> 
Keep</span>-Alive: timeout=2, max=100<span> 
Connection: Keep</span>-<span>Alive 
Transfer</span>-<span>Encoding: chunked 
Content</span>-Type: application/xml
<span>  
[XML Data]</span>

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

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

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

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

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

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

 

Cross Domain [跨域]

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

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

  如果我没加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 versions IE Firefox Chrome Safari Opera iOS Safari Opera Mini Android Browser Blackberry 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来解决。

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

  下面附上一个MSDN上的DEMO

JavaScript跨域(3):HTTP access control (CORS)跨域JavaScript跨域(3):HTTP access control (CORS)跨域XDomainRequest From MSDN

<span><span>html</span><span>></span>
<span><span>script </span><span>type</span><span>="text/javascript"</span><span>></span>
    <span>var</span><span> xdr;
    </span><span>function</span><span> readdata()
    {
        </span><span>var</span><span> dRes </span><span>=</span><span> document.getElementById(</span><span>'</span><span>dResponse</span><span>'</span><span>);
        dRes.innerText </span><span>=</span><span> xdr.responseText;
        alert(</span><span>"</span><span>Content-type: </span><span>"</span> <span>+</span><span> xdr.contentType);
        alert(</span><span>"</span><span>Length: </span><span>"</span> <span>+</span><span> xdr.responseText.length);
    }
    
    </span><span>function</span><span> err()
    {
        alert(</span><span>"</span><span>XDR onerror</span><span>"</span><span>);
    }
    </span><span>function</span><span> timeo()
    {
        alert(</span><span>"</span><span>XDR ontimeout</span><span>"</span><span>);
    }
    </span><span>function</span><span> loadd()
    {
        alert(</span><span>"</span><span>XDR onload</span><span>"</span><span>);
        alert(</span><span>"</span><span>Got: </span><span>"</span> <span>+</span><span> xdr.responseText);
    }
    </span><span>function</span><span> progres()
    {
        alert(</span><span>"</span><span>XDR onprogress</span><span>"</span><span>);
        alert(</span><span>"</span><span>Got: </span><span>"</span> <span>+</span><span> xdr.responseText);
    }
    </span><span>function</span><span> stopdata()
    {
        xdr.abort();
    }
    </span><span>function</span><span> mytest()
    {
        </span><span>var</span><span> url </span><span>=</span><span> document.getElementById(</span><span>'</span><span>tbURL</span><span>'</span><span>);
        </span><span>var</span><span> timeout </span><span>=</span><span> document.getElementById(</span><span>'</span><span>tbTO</span><span>'</span><span>);
        </span><span>if</span><span> (window.XDomainRequest)
        {
            xdr </span><span>=</span> <span>new</span><span> XDomainRequest();
            </span><span>if</span><span> (xdr)
            {
                xdr.onerror </span><span>=</span><span> err;
                xdr.ontimeout </span><span>=</span><span> timeo;
                xdr.onprogress </span><span>=</span><span> progres;
                xdr.onload </span><span>=</span><span> loadd;
                xdr.timeout </span><span>=</span><span> tbTO.value;
                xdr.open(</span><span>"</span><span>get</span><span>"</span><span>, tbURL.value);
                xdr.send();
            }
            </span><span>else</span><span>
            {
                alert(</span><span>'</span><span>Failed to create</span><span>'</span><span>);
            }
        }
        </span><span>else</span><span>
        {
            alert(</span><span>'</span><span>XDR doesn</span><span>'</span><span>t exist</span><span>'</span><span>);
        }
    }


    <h2>XDomainRequest</h2>
    <input type="text" id="tbURL" value="http://www.contoso.com/xdr.txt"></span></span></span>

 

Reference [参考资料]

  1.Mozilla

  2.MSDN

  3.http://caniuse.com/

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

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.