前端跨域总结

1.CORS (非前端跨域方法)

原理:
使用自定义的HTTP头部让浏览器与服务器沟通,从而决定请求或响应是应该成功还是失败。
方法:
浏览器的XMLHTTPRequest对象普遍实现了对CORS的原生支持,在请求不同源的资源时,会自动触发这个行为。
服务端需要根据需求来设置响应的请求头。

2.JSONP - (需要服务端允许)

原理:
web页面上获取js文件时候不受跨域影响,一般src属性都有跨域的能力。服务端允许用户传递一个callback参数给服务器,然后服务器返回数据时会将callback操作作为函数名来包裹JSON数据,这样客户端就可以随意定制自己的函数来处理返回的数据。
方法:

function handleResponse(res) {
  console.log(res);
}
var script = document.createElement("script");
script.src = 'http://moonlt.cn/userlist?name=vico&callback=handleResponse';
document.body.insertBefore(script, document.body.firstChild);

在script标签的src属性中传入接口地址,并且自定义callback处理函数,还可以传入其他参数。
注意:虽然juqery中Ajax请求的jsonp和get,post形式上相似,但并不是同一个原理,jsonp并不是ajax。
缺点:
需要服务端允许JSONP请求
只能使用GET请求

3.postMessage (HTML5新增)

原理:
一个窗口可以获得另一个窗口的引用(例如:targetWindow = window.opener),然后在当前窗口上调用targetWindow.postMessage()方法来分法一个MessageEvent消息。接收消息的窗口可以根据需求自由处理这个事件。
方法:
父窗口创建iframe并且发送消息,子窗口接收消息,并且获取event中的参数,根据消息内容请求数据,再发送给父窗口event.source.postMessage(res, event.origin);

<html lang="en">
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <title>父窗口发送信息</title>
</head>
<body>
  <textarea id="message"></textarea>
  <input type="button" value="发送" onclick="sendPost()">
  <iframe src="http://www.moonlt.cn/chat" style="display:none" id="frm"></iframe>
</body>
<script>
  var frm = document.getElementById('frm');
  frm.contentWindow.postMessage('跨域请求信息', 'http://localhost:8080");
  window.addEventListener("message", receiveMessage, false);
  function receiveMessage(event) {
  var origin = event.origin
  ...
}
</script>
</html>

注意:
可以使用任何请求方法,注意处于安全考虑,必须先检查origin和source属性来确定消息的发送者身份。

4.websocket

原理:
websocket使用了自定义协议,同源策略对其不适用,因此可以通过他打开到任何站点的连接。
方法:
跟普通使用websocket一样,通过给服务器发送消息,接收服务器发送的消息来获取数据

5.图像Ping (上古方法)

原理:
网页中加载图像,不用担心是否跨域。通过Image对象的onloadonerror事件来确定是否接收到了响应。
方法:
将图片的src替换为请求的接口(跟get方法一样),如果请求成功,会触发onloadonerror事件。
缺点:
只能发送GET请求
无法访问服务器响应文本,response为空。因此该方法只能于浏览器与服务器的单向通信(广告打点)。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。