`
mutongwu
  • 浏览: 448412 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

关于跨域的ajax——Cross-Origin Resource Sharing (CORS)

阅读更多
CORS浏览器支持:Firefox 3.5+, Safari 4+, Chrome, Safari for iOS, and WebKit for Android
//页面A: http://shawn.test2.com/crossAjax.html
function create(){
        
    var objXMLHTTP = new XMLHttpRequest();
    objXMLHTTP.open('GET', 'http://www.test.com:8080/jsp/json.jsp', true);

    //objXMLHTTP.setRequestHeader("hello","world");

    objXMLHTTP.onreadystatechange = function(){
        if(objXMLHTTP.readyState == 4){
            alert(objXMLHTTP.responseText);
        }
    };
    objXMLHTTP.send(null);
}
//后端页面B: http://www.test.com:8080/jsp/json.jsp

<%
    
    // 允许来自 http://shawn.test2.com(默认端口80)的请求。
    response.setHeader("Access-Control-Allow-Origin","http://shawn.test2.com");
    
    // 允许所有
    //response.setHeader("Access-Control-Allow-Origin","*"); 
    
    /*  cookie 设置发送到浏览器端,不会生效。
        String cookieName="Sender"; 
        Cookie cookie=new Cookie(cookieName, "Test_Content"); 
        cookie.setMaxAge(10);   //存活期为10秒
        response.addCookie(cookie); 
    */

    String str = "";
    str += "{";
    str += "\"result\":1";
    str += ",\"data\":[5,7]";
    str += "}";
    out.print(str);
%>


允许多个域名? 可以考虑把 域名做一个白名单,读取到服务器,然后再进行匹配。

上述的这种跨域请求有几个限制:
    1. 不会携带cookie信息到服务器端;服务器端也不能写cookie到客户端;
    2. 不能通过setRequestHeader()自定义头部信息;
    3. getAllResponseHeaders()返回值为空字符串。

关于预检请求(Preflighted Request):

事实上,如果用户通过setRequestHeader自定义了头部信息,浏览器会默认先发送一个请求,用了判断请求是否合法,如果不通过,
ajax请求就失败了,如果通过了,浏览器会再发一次请求,读取服务器的返回数据。

例如,上述例子中,如果调用:
    objXMLHTTP.setRequestHeader("hello","world");

则浏览器会发出请求,内容为空,请求头部为:

    OPTIONS /jsp/json.jsp HTTP/1.1
    Host: www.test.com:8080
    User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:8.0.1) Gecko/20100101 Firefox/8.0.1
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,* / * ;q=0.8
    Accept-Language: zh-cn,zh;q=0.5
    Accept-Encoding: gzip, deflate
    Accept-Charset: GB2312,utf-8;q=0.7,*;q=0.7
    Connection: keep-alive
    Origin: http://shawn.test2.com
    Access-Control-Request-Method: GET
    Access-Control-Request-Headers: hello

注意,头部请求中,多出几个选项:
    Origin: http://shawn.test2.com
    Access-Control-Request-Method: GET
    Access-Control-Request-Headers: hello

如果想采用POST方式提交ajax数据,需要手动设置
function create(){

    var objXMLHTTP = new XMLHttpRequest();
    objXMLHTTP.open('POST', 'http://www.test.com:8080/jsp/json.jsp', true);

    objXMLHTTP.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    objXMLHTTP.setRequestHeader("hello", "world");
    objXMLHTTP.onreadystatechange = function(){
        if(objXMLHTTP.readyState == 4){
            alert(objXMLHTTP.responseText);
        }
    };
    objXMLHTTP.send("userName=shawn");
}

因为这里定义请求头,所以后端也需要做设置支持:
<%
    response.setHeader("Access-Control-Allow-Origin","http://shawn.test2.com");

    //response.setHeader("Access-Control-Allow-Methods","GET,POST");    //逗号分隔;默认可以不设置。
    response.setHeader("Access-Control-Allow-Headers","Content-Type,hello");    //逗号分隔

    //预检测被缓存时间:30秒;默认可以不设置。在这个时间内,用户再次请求改数据,可以跳过预检测阶段。
    // 在firefoxV8里面,发现这个设置并没有生效。chromeV14、Safari5是生效的。
    //response.setHeader("Access-Control-Max-Age","30");

    String str = "";
    str += "{";
    str += "\"result\":1";
    str += ",\"data\":[5,7]";
    str += ",\"userName\":" + request.getParameter("userName");
    str += "}";
    out.print(str);
%>    


浏览器支持预检请求:Firefox 3.5+, Safari 4+, and Chrome

关于携带验证信息的请求(Credentialed Requests)

如果希望把cookie信息、HTTP授权信息、客户端的SSL证书等发送到服务器端。可以如下设置:
    objXMLHTTP.withCredentials = true; //允许ajax请求携带cookie信息

    // 服务器端,同样要做调整:
    response.setHeader("Access-Control-Allow-Credentials", "true");


注意:
     1. 这里面,请求携带的是 服务器所在域名的cookie。例子中,就是 www.test.com (包括test.com)的cookie信息。
     2. 如果服务端这时候设置了cookie,那么它是起作用的,默认挂在 www.test.com 域名下。


IE8+ 下的跨域对象:
    IE8+ 支持一个XDomainRequest (XDR) 对象,用来进行跨域的ajax通信。
    XDomainRequest 相比较普通的Ajax对象,有以下限制:
    1. 不支持Cookie的发送和接收;
    2. 除了 Content-type,不能设置其他请求头部;
    3. 无法读写返回头部;
    4. 仅支持 GET / POST 方法。(其它的方法的是?)
    //http://shawn.test2.com/crossAjax.html
    function createXDR(){
        var xdr = new XDomainRequest();
        xdr.onload = function(){
            alert(xdr.responseText);
        };
        xdr.onerror = function(){
            alert("An error occurred.");
        };

        //测试中,发现仅仅只能通过GET方式传值。
        xdr.open("GET", "http://www.test.com:8080/jsp/jsonie.jsp");

        // IE8 下报错
        // xdr.contentType = "application/x-www-form-urlencoded";

        //
        xdr.send();

        // 后端无法读取到POST的内容。不知道为何?
        // xdr.send("userName=shawn");
    }

    // http://www.test.com:8080/jsp/jsonie.jsp
    <%
        response.setHeader("Access-Control-Allow-Origin","*"); // allow all
        
        String str = "";
        str += "{";
        str += "\"result\":1";
        str += ",\"data\":[5,7]";
        str += ",\"userName\":" + request.getParameter("userName");
        str += "}";
        out.print(str);
    %>

总的来说,IE下出于安全的考虑,对于跨域的ajax限制很大,功能也弱。XDomainRequest也支持 progres、timeout等事件,更多内容可以参考MSDN.

参考资料:
https://developer.mozilla.org/en-US/docs/HTTP_access_control
http://msdn.microsoft.com/ZH-CN/library/cc288060
https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS?redirectlocale=en-US&redirectslug=HTTP_access_control
《javascript高级程序设计3》
分享到:
评论
1 楼 IT民工% 2014-08-26  
我想要把A的cookie信息 通过cookie属性传递给B,无法实现吗?

相关推荐

    Referrer-Policy : strict-origin-when-cross-origin解决方案

    1. **CORS(Cross-Origin Resource Sharing)**:服务器端设置Access-Control-Allow-Origin等响应头,允许特定域名的请求访问。这是推荐的解决跨域问题的标准方法。 2. **JSONP(JSON with Padding)**:通过动态...

    vue+springboot实现项目的CORS跨域请求

    跨域资源共享CORS(Cross-origin Resource Sharing),是W3C的一个标准,允许浏览器向跨源的服务器发起XMLHttpRequest请求,克服ajax请求只能同源使用的限制。关于CORS的详细解读,可参考阮一峰大神的博客:跨域资源...

    Allow-CORS_-Access-Control-Allow-Origin_v0.1.2.crx

    CORS or Cross Origin Resource Sharing is blocked in modern browsers by default (in JavaScript APIs). Installing this add-on will allow you to unblock this feature. Please note that, when the add-on ...

    Access-Control-Allow-Origin跨域问题的终极解决,给自己做备份

    2. CORS(Cross-Origin Resource Sharing):现代浏览器支持的跨域方式,通过设置Access-Control-Allow-Origin等CORS相关的响应头,允许特定或所有源进行跨域请求。CORS支持所有HTTP方法,并提供了完整的错误处理机制...

    Allow-Control-Allow- Origin.zip

    3. **CORS(Cross-Origin Resource Sharing)**:为了解决跨域限制,Web开发者可以使用CORS机制,通过在服务器端设置"Access-Control-Allow-Origin"响应头,允许特定或所有源的请求。 4. **"Access-Control-Allow-...

    Allow-Control-Allow-Origin_1_0_3_0.crx.zip

    在前端开发过程中,跨域(Cross-Origin)是一个常见的问题,特别是在使用Ajax进行API调用或者加载外部资源时。"Allow-Control-Allow-Origin_1_0_3_0.crx" 是一个Chrome浏览器扩展,用于帮助开发者解决跨域限制,以...

    cors-filter-1.7.jar,cors-filter-2.5.jar,cors-filter-2.10.jar

    在IT行业中,尤其是在Web开发领域,跨域资源共享(CORS,Cross-Origin Resource Sharing)是一个重要的概念,它允许浏览器向不同的源(域名、协议或端口)发送Ajax请求,以突破同源策略的限制。Tomcat作为一款广泛...

    Allow_CORS__Access-Control-Allow-Origin_0_1_1_0.zip

    CORS(Cross-Origin Resource Sharing)是一种W3C标准,它允许浏览器和服务器通过添加特定的HTTP头部来安全地执行跨域请求。默认情况下,由于同源策略的限制,浏览器只允许与同一源(协议+域名+端口)的网站进行交互...

    cross-request-3.0-master.zip

    1. CORS(Cross-Origin Resource Sharing,跨源资源共享):这是一种W3C标准,通过在服务器端设置特定的HTTP响应头,允许浏览器在跨域请求时进行权限判断,从而实现跨域资源访问。 2. JSONP(JSON with Padding):...

    SpringBoot实现前后端分离的跨域访问(CORS)

    CORS,即Cross-Origin Resource Sharing,跨域资源共享,是一种允许浏览器从不同源加载资源的机制。在前后端分离的架构中,由于前端和后端可能部署在不同的域名下,跨域问题就显得尤为重要。SpringBoot提供了多种...

    Allow-Control-Allow-Origin.rar

    为了解决这个问题,Web开发者可以使用CORS(Cross-Origin Resource Sharing,跨源资源共享)机制。CORS通过在服务器端设置响应头`Access-Control-Allow-Origin`来允许特定或所有来源的请求。这就是压缩包中可能包含...

    Spring boot 和Vue开发中CORS跨域问题解决

    跨域资源共享CORS(Cross-origin Resource Sharing),是W3C的一个标准,允许浏览器向跨源的服务器发起XMLHttpRequest请求,克服ajax请求只能同源使用的限制。关于CORS的详细解读,可参考阮一峰大神的博客:跨域资源...

    Allow-Control-Allow-Origin-小军617

    标题“Allow-Control-Allow-Origin-小军617”和描述中的...对于更复杂的应用场景,可以考虑使用CORS(Cross-Origin Resource Sharing)进行服务器端的跨域配置,或者使用JSONP(JSON with Padding)等其他跨域技术。

    cors技术解决ajax跨域

    为了解决这个问题,CORS(Cross-Origin Resource Sharing,跨源资源共享)应运而生。CORS提供了一种安全的方式来允许浏览器和服务器之间进行跨域通信,使得开发者可以突破同源策略的限制。 **一、CORS的工作原理** ...

    Allow-Control-Allow-Origin

    为了克服这一限制,开发者可以使用CORS(Cross-Origin Resource Sharing,跨源资源共享)机制。 CORS通过在服务器端设置特定的HTTP响应头"Access-Control-Allow-Origin"来允许特定的源进行跨域请求。这个头的值可以...

    ajax跨域调用wcf实例--改分重传

    - CORS(Cross-Origin Resource Sharing):这是一种现代浏览器支持的机制,允许服务器指定哪些源可以访问其资源。WCF服务端设置`Access-Control-Allow-Origin`头来允许特定的源进行跨域请求。 在提供的...

    跨域请求资源-jsonp和cors区别.pdf

    - **CORS**(Cross-Origin Resource Sharing,跨源资源共享)是一个W3C标准,用于定义服务器如何响应来自不同源的HTTP请求。 - CORS由服务器端配置完成,主要通过HTTP头部中的`Access-Control-Allow-Origin`字段来...

    demo跨域ajax_DEMO_ajax跨域_

    为了解决C#服务器与JavaScript客户端的跨域通信,我们需要采用跨域资源共享(CORS,Cross-Origin Resource Sharing)机制。CORS是一种W3C标准,允许服务器声明哪些源可以访问其资源。在C# ASP.NET环境中,可以通过...

    跨域、cors-filter-1.7、java-property-utils-1.9

    在Web开发中,跨域(Cross-Origin Resource Sharing, CORS)是一个关键的概念,它涉及到浏览器的安全策略,限制了JavaScript从一个源获取资源到另一个源。为了克服这个限制,开发者需要使用CORS机制。本文将深入探讨...

Global site tag (gtag.js) - Google Analytics