zoukankan      html  css  js  c++  java
  • [转]跨域资源共享(CrossOrigin Resource Sharing)实现Ajax跨域请求

    原文链接:http://www.cnblogs.com/yoyiorlee/archive/2010/11/07/1871308.html

    最近正在做的几个项目都用到了Ajax跨域请求,由于处于安全的角度,Firefox、Chrome等很多浏览器(IE除开)都不允许跨域请求或调用,折腾好久,终于解决了Ajax跨域请求这个蛋疼的问题,在网上也找了很久的资料,尝试N次都失败,今天在无意之中看到一篇跨域资源共享的文章,这让我轻松的解决了跨域问题,不多说。

    跨域请求,就是一个站点中的资源去访问另外一个不同域名站点上的资源。这种情况很常见,比如说通过 <link> 标签加载外部样式表文件、通过 <img> 标签加载外部图片、通过 <script> 标签加载外部脚本文件等等。默认情况下,脚本访问文档属性等数据采用的是同源策略(Same origin policy)

    如果两个页面的协议、域名和端口是完全相同的,那么它们就是同源的。 如果两个页面的主域名相同,则还可以通过设置 document.domain 属性将它们认为是同源的。

    随着 Web2.0 和 社交网络 的兴起,Web 应用对跨域访问的需求也越来越多,但是在脚本中进行跨域请求是受安全性限制的。比如分布式应用,主网站和二级域名网站的通信等等。

    许多人还没意识到当前几乎所有的浏览器(Internet Explorer 8+, Firefox 3.5+, Safari 4+和 Chrome)都可通过名为跨域资源共享(Cross-Origin Resource Sharing)的协议支持ajax跨域调用。 对一个简单的请求,没有自定义头部,要么使用GET,要么使用POST,它的主体是text/plain,请求用一个名叫Orgin的额外的头部发送。Origin头部包含请求页面的头部(协议,域名,端口),这样服务器可以很容易的决定它是否应该提供响应。

    在IE8中也是一样,用同样的方式你需要使用XDomainRequest object

     var xdr = new XDomainRequest();
    xdr.open("get""http://www.msnova.net/resource/");
    xdr.onload 
    = function(){
    //do something
    };
    xdr.send(); 

    方法一:跨域资源共享(Cross-Origin Resource Sharing)实现Ajax跨域请求  (跨域资源共享,该规范地址:http://www.w3.org/TR/access-control/和http://dev.w3.org/2006/waf/access-control/)

    1.在客服端写下面代码

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"  
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
    >  
    <html xmlns="http://www.w3.org/1999/xhtml">  
    <head>  
      
    <title>AJAX跨域请求测试</title>  
    </head>  
    <body>  
      
    <input type='button' value='开始测试' onclick='cross_domain_request()' />  
      
    <div id="content"></div>  
      
    <script type="text/javascript"> 
        
    var xhr = new XMLHttpRequest();  
        
    var url = 'http://www.msnova.net/resource/';  
        
    function cross_domain_request() {  
          document.getElementById(
    "content").innerHTML = "开始……";  
          
    if (xhr) {  
            xhr.open(
    'GET', url, true);  
            xhr.onreadystatechange 
    = handler;  
            xhr.send();  
          } 
    else {  
            document.getElementById(
    "content").innerHTML = "不能创建 XMLHttpRequest";  
          }  
        }  
        
    function handler(evtXHR) {  
          
    if (xhr.readyState == 4) {  
            
    if (xhr.status == 200) {  
              
    var response = xhr.responseText;  
              document.getElementById(
    "content").innerHTML = "结果:" + response;  
            } 
    else {  
              document.getElementById(
    "content").innerHTML = "不允许跨域请求。";  
            }  
          }  
          
    else {  
            document.getElementById(
    "content").innerHTML += "<br/>执行状态 readyState:" + xhr.readyState;  
          }  
        }  
    </script>  
    </body>  
    </html>

    2.在服务端写(可写在前台页面,也可在后台文件中写)

     <%@ Page Language="C#" %>  

    <script runat="server"> 
      protected 
    void Page_Load(object sender, EventArgs e)  
      {  
        Response.AddHeader(
    "Access-Control-Allow-Origin""http://www.yoursite.com:8080");  
        Response.Write(
    "孟宪会向各位朋友发来贺电:你的第一个跨域测试成功啦!!!");  
      }  
    </script>

     注意:在请求信息中,浏览器使用 Origin 这个 HTTP 头来标识该请求来自于 http://www.yoursite.com:8080;在返回的响应信息中,使用 Access-Control-Allow-Origin 头来控制哪些域名的脚本可以访问该资源。如果设置 Access-Control-Allow-Origin:*,则允许所有域名的脚本访问该资源。如果有多个,则只需要使用逗号分隔开即可。

     注意:在服务器端,Access-Control-Allow-Origin 响应头 http://www.yoursite.com:8080 中的端口信息不能省略。

     如果想实现 XMLHttpRequest 来请求任意一个网站的数据,则需设置:

     Response.AddHeader("Access-Control-Allow-Origin", "http://www.yoursite.com:8080");

     这行代码就告诉浏览器,只有来自 http://www.yoursite.com:8080 源下的脚本才可以进行访问。

     推荐阅读:http://blog.csdn.net/net_lover/archive/2010/01/11/5172509.aspx

     这样就可以实现跨域请求了,总结一下网上的方法,我绝不错的

    方法二:document.domain+iframe

     对于主域相同而子域不同的例子,可以通过设置document.domain的办法来解决。具体的做法是可以在http://www.msnova.net/a.html和http:// blogs.msnova.net/b.html两个文件中分别加上document.domain = ‘msnova.net’;

    然后通过a.html文件中创建一个iframe,去控制iframe的contentDocument,这样两个js文件之间就可以“交互”了。当然这种办法只能解决主域相同而二级域名不同的情况

    www.msnova.net上的a.html 

         document.domain = 'msnova.net';

        var ifr = document.createElement('iframe');
        ifr.src 
    = 'http://script.msnova.net/b.html';
        ifr.style.display 
    = 'none';
        document.body.appendChild(ifr);
        ifr.onload 
    = function(){
            
    var x = ifr.contentDocument;
            alert(x.getElementsByTagName(
    "h1")[0].childNodes[0].nodeValue);
        

     script.msnova.net上的b.html

    document.domain = 'msnova.net'; 

    补充:同源策略:

    URL 说明 是否允许通信
    http://www.msnova.net/lab/a.html
    http://www.msnova.net/script/b.html
    同一域名下不同文件夹 允许
    http://www.msnova.net/a.html
    http://www.msnova.net/b.html
    同一域名下 允许
    http://www.msnova.net:8000/a.html
    http://www.msnova.net/b.html
    同一域名,不同端口 不允许
    http://www.msnova.net/a.html
    https://www.msnova.net/b.html
    同一域名,不同协议 不允许
    http://www.msnova.net/a.html
    http://70.32.92.74/b.html
    域名和域名对应ip 不允许
    http://www.msnova.net/a.html
    http://blogs.msnova.net/b.html
    主域相同,子域不同 不允许
    http://www.cnblogs.com/a.html
    http://www.msnova.net/b.html
    不同域名 不允许
  • 相关阅读:
    串匹配模式中的BF算法和KMP算法
    “隐藏与显示”的多种方法实现
    原生js实现tooltip提示框的效果
    心向旋转巧得木马 峰回路转偶得时钟
    jQuery 之 验证表单
    Java代码添加背景音乐
    svg动画 之 我的自制太阳系
    java_22 Map接口
    java_22.1 Map 的应用
    java_18 Collection接口
  • 原文地址:https://www.cnblogs.com/scgw/p/1982842.html
Copyright © 2011-2022 走看看