关于跨域

一、jsonp

由于浏览器一般不对script,img等进行跨域限制,所以我们有机会通过script的方式来实现跨域访问。但img、iframe、script等标签是个例外,这些标签可以通过src属性请求到其他服务器上的数据。

JSONP的缺点则是:它只支持GET请求而不支持POST等其它类型的HTTP请求;它只支持跨域HTTP请求这种情况,不能解决不同域的两个页面之间如何进行JavaScript调用的问题。
允许用户传递一个callback参数给服务端,然后服务端返回数据时会将这个callback参数作为函数名来包裹住JSON数据,这样客户端就可以随意定制自己的函数来自动处理返回数据了。

客户端http://localhost:8080访问服务器http://localhost:11111/user,正常情况下,这是不允许的。因为这两个URL是不同域的。
callbackfunction({"id":1,"name":"test"})
  
<script>  
  var url = "http://localhost:8080/crcp/rcp/t99eidt/testjson.do?jsonp=callbackfunction";   
  var script = document.createElement('script');   
script.setAttribute('src', url);  //load javascript    
  document.getElementsByTagName('head')[0].appendChild(script);   
  
  //回调函数  
   function callbackfunction(data){  
var html=JSON.stringify(data.RESULTSET);  
alert(html);  
     }  
</script>  

二、cors跨域资源共享 corss-origin-resourse-sharing

 1)JSONP主要被老的浏览器支持,它们往往不支持CORS,而绝大多数现代浏览器都已经支持了CORS。
2)使用CORS,开发者可以使用普通的XMLHttpRequest发起请求和获得数据,比起JSONP有更好的错误处理。
Access-Control-Allow-Origin: http://blog.csdn.net 接收-控制-允许-来源

服务端会在HTTP请求头中增加一系列HTTP请求参数(例如Access-Control-Allow-Origin等),来限制哪些域的请求和哪些请求类型可以接受,而客户端在发起请求时必须声明自己的源(Origin),否则服务器将不予处理,如果客户端不作声明,请求甚至会被浏览器直接拦截都到不了服务端。服务端收到HTTP请求后会进行域的比较,只有同域的请求才会处理。
// 声明请求源
xhr.setRequestHeader("Origin", "http://a.example.com");

//浏览器直接发出CORS请求。具体来说,就是在头信息之中,增加一个Origin字段。


三、postMessage方法
1)页面与内嵌的iframe消息传递
源页面:
<iframe id="child" src="http://lsLib.com/lsLib.html"></iframe>
window.οnlοad=function(){ window.frames[0].postMessage('mysource','http://lslib.com');
window.addEventListener('message',function(e){
console.log(e.data);
});}
目标页面:
window.addEventListener('message',function(e) {
if(e.origin !== window.parent){ // 判断数据发送方是否是可靠的地址
return false;
}
console.log(e.data);//打印接收到的数据对象
/*回发数据*/
e.source.postMessage('hello world', e.origin);
});

2)通过window.open()打开新的页面
源目标:
document.getElementById('btn').onclick =function() {
var newWindow =window.open('http://3.wenphp.sinaapp.com/test/newwindow.html');
//注册监听信息事件,看看是否有数据发送过来
window.addEventListener('message', function (e) {
if(e.data==='true'){//要是新窗口有数据返回过来,说明新窗口已经完全加载。然后才能够给新窗口发送数据
newWindow.postMessage('hello world!', e.origin);//给新窗口发送数据
console.log(e);//打印新窗口返回来的数据
}
});

目的目标:
window.opener.postMessage('true', 'http://www.w3cfuns.com');//发送一个数据给源窗口,用于判断通过open打开的窗口是否装载完成。
/*监听看有没有数据发送过来*/
window.addEventListener('message',function(e) {
if(e.origin !== "http://www.w3cfuns.com"){ // 判断数据发送方是否是可靠的地址
return false;
}
console.log(e.data);//打印接收到的数据对象
})

四、document.domain
前提条件:这两个域名必须属于同一个基础域名!而且所用的协议,端口都要一致,否则无法利用
比如在:aaa.com的一个网页(a.html)里面 利用iframe引入了一个bbb.com里的一个网页(b.html)。
这时在a.html里面可以看到b.html里的内容,但是却不能利用javascript来操作它。因为这两个页面属于不同的域,在操作之前,js会检测两个页面的域是否相等,如果相等,就允许其操作,如果不相等,就会拒绝操作。
这里不可能把a.html与b.html利用JS改成同一个域的。因为它们的基础域名不相等。(强制用JS将它们改成相等的域的话会报跟上面一样的"参数无效错误。")
所以如果在a.html里引入aaa.com里的另一个网页,是不会有这个问题的,因为域相等。

有另一种情况,两个子域名:aaa.xxx.com和bbb.xxx.com
aaa里的一个网页(a.html)引入了bbb 里的一个网页(b.html),这时a.html里同样是不能操作b.html里面的内容的。因为document.domain不一样,一个是aaa.xxx.com,另一bbb.xxx.com。
这时我们就可以通过Javascript,将两个页面的domain改成一样的,需要在a.html里与b.html里都加入:
document.domain = "xxx.com";这样这两个页面就可以互相操作了。也就是实现了同一基础域名之间的"跨域"。

五、window.name
name 值在不同的页面(甚至不同域名)加载后依旧存在,并且可以支持非常长的 name 值(2MB)。
当该window的location变化,然后重新加载,它的name属性可以依然保持不变。 那么我们可以在页面A中用iframe加载其他域的页面B,而页面B中用JavaScript把需要传递的数据赋值给window.name,iframe加载完成之后,页面A修改iframe的地址,将其变成同域的一个地址,然后就可以读出window.name的值 了。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值