js跨域

来源:互联网 发布:数控车床g84攻牙编程 编辑:程序博客网 时间:2024/06/11 03:47

由于安全的原因,浏览器做了很多方面的工作,由此也就引入了一系列的跨域问题,需要注意的是:跨域并非浏览器限制了发起跨站请求,而是跨站请求可以正常发起,但是返回结果被浏览器拦截了。最好的例子是 CSRF 跨站攻击原理,请求是发送到了后端服务器无论是否跨域!注意:有些浏览器不允许从HTTPS的域跨域访问HTTP,比如Chrome和Firefox,这些浏览器在请求还未发出的时候就会拦截请求,这是一个特例。

跨域例子

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <script src="./jquery-1.8.2.js"></script>   </head><script>$(function(){    $("#postBtn").click(function(){        console.log("访问开始");        $.ajax({            url:"http://hq.sinajs.cn/rn=9pl6s&list=SGE_AU99_99",            data:{},            type:"POST",            success:function(data){                console.log(data);            },            error:function(request,status,e){                alert("异常!");            }        });    });});</script><body>    <button id="postBtn">跨域访问开始</button></body></html>

结果为:
XMLHttpRequest cannot load http://hq.sinajs.cn/rn=9pl6s&list=SGE_AU99_99. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.

JSONP

JSONP的全称是 “JSON With Padding”,词面意思上理解就是”填充式的JSON”。

因为src属性没有受到跨域的限制,所以我们可以利用script来解决跨域带来的问题。
原理:
a站下的一个a.jsp文件访问b站上的一个b.js文件,而b站的b.js是动态生成的一个文件,b.js可以调用a.jsp中的一个js方法,并且把该方法需要的数据通过参数传递过来。
一个简单的例子:

<!--a.jsp--><!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title></title></head><script>function callback(data){    console.log(data.url);}</script><script src="b.js"></script><body>  </body></html>
//b.jscallback({url:"http:www.recodre.net"})

callback是两个文件约定好的一个方法名。

jQuery让开发更便捷

$.ajax({    method: 'jsonp',    url: 'http://***.com?oper=**',    success: function(data) {        console.log(data);    }});

但是,jsonp只支持GET方式的请求,只支持HTTP请求这种特殊的情况,对于两个不同域之间两个页面的互相调用也是无能为力。

CORS

可以在服务器端进行一些定义,允许部分网络访问。
CORS 的全称是 Cross-Origin Resource Sharing,即跨域资源共享。他的原理就是使用自定义的 HTTP 头部,让服务器与浏览器进行沟通,主要是通过设置响应头的 Access-Control-Allow-Origin 来达到目的的。这样,XMLHttpRequest 就能跨域了。
值得注意的是,正常情况下的 XMLHttpRequest 是只发送一次请求的,但是跨域问题下很可能是会发送两次的请求(预发送)。
更加详细的内容可以参见

window.name

window.name 在一个窗口(标签)的生命周期之内是共享的,利用这点就可以传输一些数据。

a.html<script type="text/javascript">    var state = 0,     iframe = document.createElement('iframe'),    loadfn = function() {        if (state === 1) {            var data = iframe.contentWindow.name;    // 读取数据            alert(data);    //弹出'I was there!'        } else if (state === 0) {            state = 1;            iframe.contentWindow.location = "http://a.com/proxy.html";//设置的代理文件。contentWindow属性是指指定的frame或者iframe所在的window对象,更改的就是这个对象的name,并且该对象是不可见的。        }      };    iframe.src = 'http://b.com/b.html';    if (iframe.attachEvent) {        iframe.attachEvent('onload', loadfn);    } else {        iframe.onload  = loadfn;    }    document.body.appendChild(iframe);</script>
b.html<script type="text/javascript">    window.name = 'I was there!';    // 这里是要传输的数据,大小一般为2M,IE和firefox下可以大至32M左右                                     // 数据格式可以自定义,如json、字符串</script>

document.domain

location.hash

window.postMessage()

原文地址

0 0
原创粉丝点击