跨域-jsonp、cors、iframe、document.domain、postMessage()

同源策略

概念:同源: 协议、域名、端口号 完全相同

同源策略是浏览器的一种安全策略;且浏览器不会将违反同源策略的响应信息返回

http://127.0.0.1:3000/index.html         http://127.0.0.1:3000/hello.html

http://localhost:3000/hello.html          https://localhost:3000/hello.html 

eg: 协议名---  http、https  域名--- 127.0.0.1、localhost                                                                                                            

不同源

概念:协议名、域名、端口有其一不同,即不同源;

跨域:js跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,只要协议、域名、端口有任何一个不同,都被当作是不同的域。 

简言之,不同源就是跨域,

1.JSONP

全称:JSON with Padding;            

作用:利用一些HTML标签天生的跨域能力来发送跨域请求的  eg:img、script、link

缺点:JSONP只能发送get请求,不能发送post请求,且JSONP不是官方的跨域解决方案

原理:

原生js :

原理: 

① 首先当前页面中声明有一个函数,dosomething

② 借助 <script><img><iframe> 等标签可以引入不同域资源的特性,将需要发送的请求的路径作为src参数,且带上将之前约定好的回调函数名,callback=dosomething

③ 服务端接收到请求后,就会返回一端 js代码,在 js代码中调用了约定好的回调函数,并且需要返回的数据作为回调函数的参数dosomething([a,,b,c])

④ 当网页接收到这段 js 代码,执行这个回调函数,这时数据已经成功传输到客户端了。

 jQuery

 * 客户端  url?callback=?

 * 服务器端

        var callback = req.query.callback  ----返回的value需要封装成jsonObj

        res.send(callback+'('+jsonObj+')');

$.getJSON方法会自动判断是否跨域,不跨域的话,就调用普通的ajax方法;跨域的话,则会以异步加载js文件的形式来调用jsonp的回调函数。

 2.CORS

全称:Cross-Origin Resource 跨域资源共享

优点:CORS是官方的跨域解决方案,且使用CORS不需要在客户端做任何修改,直接发送AJAX请求即可

   CORS支持get/post请求;IE8以下不支持

方法:通过服务器设置一个响应头来告诉浏览器允许跨域请求

res.sendHeader(‘Access-Control-Allow-Origin’,’请求地址’)

允许所有的跨域请求 用 *    即 res.sendHeader(‘Access-Control-Allow-Origin’, ’*’ )

response.setHeader(Access-Control-Allow-Credentials:true)  //-可选-设置是否允许发送cookie

response.setHeader(Access-Control-Allow-Methods‘post’、‘get’)

response.addHeader(Access-Control-Max-Age: 600) 注:单位是秒

response.addHeader(Access-Control-Allow-Headers:origin, x-requested-with出现的首部信息

 3.iframe

window.name + iframe ==> http://www.tuicool.com/articles/viMFbqV,支持跨主域。不支持POST

在iframe中获取父级内容

同理,在同域下,父页面可以获取子iframe的内容,那么子iframe同样也能操作父页面内容

 4.document.domain来跨子域

例如  a.qq.com嵌套一个b.qq.com的iframe ,如果a.qq.com设置document.domain为qq.com 。b.qq.com设置document.domain为qq.com,那么他俩就能互相通信了,不受跨域限制了。

注意:只能跨子域

5.postMessage()

window.postMessage(message,targetOrigin)  此方法是html5新引进的特性,

优点:可以使用它来向其它的window对象发送消息,无论这个window对象是属于同源或不同源(目前IE8+、FireFox、Chrome、Opera等浏览器都已经支持)。

缺点:缺点是IE6、IE7不支持,所以用不用还得根据实际需要来决定。

具体来说:调用postMessage方法的window对象是指要接收消息的那一个window对象,通过监听自身的message事件来获取传过来的消息,消息内容储存在该事件对象的data属性中。

  第一个参数message为要发送的消息,类型只能为字符串;

  第二个参数targetOrigin用来限定接收消息的那个window对象所在的域,如果不想限定域,可以使用通配符 *  。

<script>    
function onLoad(){
     var iframe = document.getElementById('iframe');
    var  obj = iframe.contentWindow;
    obj.postMessage('我是来自a的信息哦',‘*’)
}
</script>  
<iframe id="iframe" src='http://www.test.com/b.html' onload="onLoad()"></iframe>
<script>    
window.onmessage = function (e){
   event = event ||e 
    console.log(e.data) //通过data属性得到a传来的信息
}
</script>  

 

原文地址:https://www.cnblogs.com/renzm0318/p/8962189.html