我爱编程

跨域解决方案

2018-04-14  本文已影响39人  咕嘟咕嘟li

举例URL: https://www.stuspy.com/mxsj/paperTest.html?id=5a56d694ac502e0042d73dce

跨域的几种情况

跨域解决方案

1.CORS(主要解决的是异域之间的传值)

跨源资源共享定义了在必须访问跨源资源时,浏览器与服务器该如何沟通。其背后的基本思想就是使用自定义的HTTP头部让浏览器与服务器进行沟通,从而决定请求或响应是否应该成功。

2.图像Ping

图像Ping——最常用于跟踪用户点击页面或动态广告曝光次数。有两个主要的缺点,一是只能发送GET请求,二是无法访问服务器的响应文本。因此,图像Ping只能用于浏览器与服务器间的单向通信。

3.JSONP

JSONP(JSON with padding的简写)——是一种基于文本的数据交换方式,或者叫做数据描述格式。jsonp通过动态<script>元素来使用的,使用时可以为src属性指定一个跨域URL,因为 JSONP 是有效的 JavaScript 代码,所以在请求完成后,即在 JSONP 响应加载到页面中以后,就会立即执行。

JSONP的优点:

在于能够直接访问响应文本,支持在浏览器与服务器之间双向通信。

JSONP的不足:

4.window.postMessage()

window.postMessage()方法被调用时,会在所有页面脚本执行完毕之后,向目标窗口派发一个 MessageEvent消息。

message 的属性有:
data:从其他 window 中传递过来的对象。
origin:调用 postMessage 时消息发送方窗口的 origin . 这个字符串由 协议、“://“、域名、“ : 端口号”拼接而成。请注意,这个origin不能保证是该窗口的当前或未来origin,因为postMessage被调用后可能被导航到不同的位置
source:对发送消息的窗口对象的引用; 可以使用它来在具有不同origin的两个窗口之间建立双向通信。

window.postMessage()安全问题
  1. 如果不希望从其他网站接收message,就不要为message事件添加任何事件侦听器
  2. 始终使用origin和source属性验证发件人的身份
// 消息发送方
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>请求页面</title>
</head>
<body>
<div>
    <p>这里是2000端口</p>
    <input type="text"/>
    <button>发送信息</button>
    <p style="text-align: left;">message :  <span></span></p>
</div>
<iframe  id="child" src="http://localhost:2001"></iframe>
<script>
    var input = document.getElementsByTagName('input')[0];
    var btn = document.getElementsByTagName('button')[0];
    var frame = document.getElementById('child').contentWindow;
    btn.onclick = function () {
      var msg = input.value;
      frame.postMessage('收到信息:' + msg + ' --from 2000 port!', 'http://localhost:2001');
    }
</script>
</body>
</html>
// 消息接收方
// 注册message事件并绑定事件监听函数
if (window.addEventListener) { 
  window.addEventListener('message', receiveMessage, false);
 } else {
   window.attachEvent('message', receiveMessage);
}
function receiveMessage(event) {
  // For Chrome, the origin property is in the event.originalEvent
  var origin = event.origin || event.originalEvent.origin; 

  // 使用origin或source属性验证发件人的身份
  if (origin !== "http://localhost:2000") { // http://localhost:2000为自己定义的地址
    return;
  }

  // Do Something ...
  var data = event.data;
  console.log(data)
}

该跨域方法适合于同一页面的不同窗体(iframe)

5.document.domain(主要解决的是子域与父域之间的传值)

现有父域:http://b.com/b.com.html
要向子域:http://a.b.com/a.b.com.html获取数据
两个域都设置如下:

 document.domain = 'b.com'; //设置成主域

这样就解决了子域与父域间的跨域问题

6. 后端设置代理proxy跨域

var express = require('express');
var proxy = require('http-proxy-middleware');

var requestPort = 2000; 
var app = express();

app.use(express.static(__dirname));

app.use('/api', proxy({target: 'http://localhost:2001/', changeOrigin: true}));
// changeOrigin设置为true,本地会虚拟一个服务端接收你的请求并代你发送该请求
// http://localhost:2000/api   -->   http://localhost:2001/api

app.listen(requestPort, function () {
    console.log('Requester is listening on port '+ requestPort);
});

7.WebSocket跨域

Web Sockets 是一种与服务器进行全双工、双向通信的信道。与其他方案不同,Web Sockets 不使用HTTP 协议,而使用一种自定义的协议——WebSocket 通信

上一篇 下一篇

猜你喜欢

热点阅读