您的位置:首页 > Web前端 > JavaScript

js跨域

2016-03-04 15:30 741 查看
由于安全的原因,浏览器做了很多方面的工作,由此也就引入了一系列的跨域问题,需要注意的是:跨域并非浏览器限制了发起跨站请求,而是跨站请求可以正常发起,但是返回结果被浏览器拦截了。最好的例子是 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.js
callback({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()

原文地址
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: