跨域

作者: innerwang | 来源:发表于2018-12-27 12:21 被阅读0次

    要了解跨域首先需要了解同源策略。

同源策略

    浏览器出于安全的考虑,当页面向非本域(同协议,同域名以及同端口)的接口请求数据时,无法读写对方的资源。虽然这些限制是必要的,但是也会使合理的用途受到影响,因此就需要跨域,绕过上述限制获取数据。需要注意的是,同源策略是浏览器的限制,换个场景则不一定存在,比如微信浏览器、服务端发请求等

一、JSONP(JSON with padding) 实现跨域

  JSONP是一种通过加载<script>标签绕过同源策略来请求数据的javascript模式。
  HTML的<script>标签可以调用服务器提供的js脚本,使用<script>标签向某个链接发送请求获取数据时,服务器返回的是JSON格式的数据,直接作为js去执行必然会报错。则我们可以提前在页面声明一个函数,并将函数名通过接口传参的方式传递给后台,当后台解析url的pathname得到函数名时使用“函数名(原始数据)”的形式发送给前端,前端在收到数据时则可以直接执行该函数,在函数内部处理原始数据即可。

/* req.js */
<script>
function parseResponse(ret){
   console.log(ret);
}
</script>
<script type="application/javascript"
        src="http://server.example.com/Users/student.json?callback=parseResponse">
</script>

二、CORS(Cross-Origin Resource Sharing) 实现跨域

  cors是一种ajax跨域请求资源的方式,支持现代浏览器及IE10以上。cors的请求分为简单请求(simple request)和非简单请求(not-so-simple request)两类。在此主要介绍简单请求的实现方式。
  当使用 XMLHttpRequest 发送请求时,浏览器发现请求不符合同源策略时,会给该请求加一个请求头:Origin(用来说明本次请求来自哪个源(协议 + 域名 + 端口)),后台会进行一系列处理,如果确定接受请求则在返回结果中加入一个响应头:Access-Control-Allow-Origin; 浏览器判断该相应头中是否包含 Origin 的值,如果有则浏览器会处理响应,我们就可以拿到响应数据,如果不包含浏览器直接驳回,这时我们无法拿到响应数据。
使用 XMLHttpRequest发送ajax请求如下:

var xhr = new XMLHttpRequest()
    xhr.open('GET', 'http://127.0.0.1:8080/getNews', true)
    xhr.send()
    xhr.onload = function(){
      appendHtml(JSON.parse(xhr.responseText))
    }

当在浏览器通过http://localhost:8080/index.html打开页面时,会向http://127.0.0.1:8080/getNews请求数据,此时浏览器检测属于跨域请求,则会在Requese Headers中添加Origin: http://localhost:8080,后端服务器会在返回的Response Headers中包含Access-Control-Allow-Origin: http://localhost:8080,此时包含origin的值,则浏览器会处理响应数据。



三、降域

举例来说,A网页是http://w1.example.com/a.html,B网页是http://w2.example.com/b.html,那么只要设置相同的document.domain,则可以互相访问数据。

document.domain = 'example.com';

四、window.postMessage()

··window.postMessage()方法被调用时,会在所有页面脚本执行完毕之后(e.g., 在该方法之后设置的事件、之前设置的timeout 事件,etc.)向目标窗口派发一个 MessageEvent消息。目标窗口若要接收消息则只需要监听window的message事件即可。

/*postMessage方法的调用格式*/
otherWindow.postMessage(message, origin);
  • otherWindow是对要发送消息的窗口的一个引用
  • message 是要发送到其他window的数据
  • origin 用于指定哪些窗口能接收到消息事件
/*接收消息的页面的处理*/
window.addEventListener("message", receiveMessage(e){
  if(e.source!=window.parent) return;
  var color=document.querySelector('.container').style.backgroundColor;
  window.parent.postMessage(color,'*');
},false)

相关文章

网友评论

      本文标题:跨域

      本文链接:https://www.haomeiwen.com/subject/qvohlqtx.html