欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

javaWeb - 同源策略: Jsonp & CORS

程序员文章站 2024-02-18 23:53:46
...

博文内容总结自文章:浏览器家族的安全反击战

同源策略

同源是指{protocol,host,port} 这三个东西必须得一样! 例如有这么一个网页: http://www.store.com/product/page.html, 下面的表格列出了各种不同情况:
javaWeb - 同源策略: Jsonp & CORS

使用同源策略的原因

  1. Cookie失窃,非法网页通过javascript访问其他应用的服务器,获取到Cookie后伪装成用户进行非法操作。
  2. 通过iframe伪装form,将信息提交到恶意action,隐私数据提交到了不法网站,信息被盗取。
    javaWeb - 同源策略: Jsonp & CORS

同源策略的限制

有src属性的标签不受同源策略的影响。比如script、img、iframe、link。相当于浏览器发送get请求。原页面的js不能访问通过src加载的资源。

如果两个网页的一级域名是相同的,他们可以共享cookie, 不过cookie的domain一定要设置为那个一级域名才可以,例如:
”document.cookie = ‘test=true;path=/;domain=store.com’”

对于浏览器来说:除了DOM、Cookie、LocalStorage、XMLHttprequest(Ajax)会受到同源策略的限制外,浏览器加载的第三方插件也有各自的同源策略。例如:flash,java applet,silverlight等。

既然服务器(domain)之间是互信的,那一个服务器(domain)可以设置一个白名单,里边列出它允许哪些服务器(domain)的AJAX请求。假设movie.com的白名单中有book.com, 那当属于book.com的JavaScript试图访问movie.com的时候,book.com先询问movie的白名单中是否有自己(是否允许自己访问),有就继续访问。
这个方法叫做Cross Origin Resource Sharing,简称CORS,只不过这个方法需要服务器的配合。

jsonp

jsonp 的原理很简单,利用了【前端请求静态资源的时候不存在跨域问题】这个思路,但是只支持 get。既然这个方法叫 jsonp,后端数据一定要使用 json 数据。

前端 jQuery 写法

   $.ajax({  
            url:"http://crossdomain.com/services.php",  
            dataType:'jsonp',  
            data:'',  
            jsonp:'callback',  
            success:function(result) {  
                for(var i in result) {  
                    alert(i+":"+result[i]);//循环输出a:1,b:2,etc.  
                }  
        },  
            timeout:3000  
    });  

后端 SpringMVC 配置

@ControllerAdvice
public class JsonpAdvice extends AbstractJsonpResponseBodyAdvice {
    public JsonpAdvice(){
        // 这样如果请求中带 callback 参数,Spring 就知道这个是 jsonp 的请求了
        super("callback");
    }
}

以上写法要求 SpringMVC 版本不低于 3.2 。

原理

首先在客户端注册一个callback方法(javaScript定义一个指定名字的回调方法), 然后把callback的名字传给服务器。服务器先生成 json 数据。然后以 javascript 语法的方式,生成一个function , function 名字就是传递上来的回调函数的名字。

最后将 json 数据直接以入参的方式,放置到 function 中,这样就生成了一段 js 语法的文档,返回给客户端。

客户端浏览器,解析script标签,并执行返回的 javascript 文档,此时数据作为参数,传入到了客户端预先定义好的 callback 函数里.(动态执行回调函数)

CORS

Cross-Origin Resource Sharing

通过服务器端中转,例如你是来自book.com的, 现在想访问movie.com,那可以让那个book.com把请求转发给movie.com!利用了代理模式,book.com就是代理人。但在正式访问之前需要先发送预检请求(preflight request)确认自己能访问。

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

javaWeb - 同源策略: Jsonp & CORS

CORS需要服务器的配合,CORS 支持以下浏览器,不过目前来看,浏览器的问题已经越来越不重要了。
Chrome 3+
Firefox 3.5+
Opera 12+
Safari 4+
Internet Explorer 8+

前端 jQuery 写法

$.ajax({
    type: "POST",
    url: "...url...",
    dataType: 'json',
    crossDomain: true,
    xhrFields: {
        withCredentials: true
    },
    data: {
        name: "name_from_frontend"
    },
    success: function (response) {
        console.log(response)// 返回的 json 数据
        $("#response").val(JSON.stringify(response));
    }
});

crossDomain: true,这里代表使用跨域请求
xhrFields: {withCredentials: true},这样配置就可以把 cookie 带过去了,不然 session 无法维护(cookie中保存了JSESSIONID),如果没有这个需求,也就不需要配置。


—END—