跨域通信的几种方式
跨域通信的几种方式
- JSONP
- Hash(hash改变,页面不刷新)
- postMessage(hmtl5中新增加的,用来实现跨域)
- WebSocket(不受同源限制)
- CORS(支持跨域通信的AJAX,浏览器会拦截AJAX请求,如果是跨域的,在HTTP头中加一个origin)
JSONP
jsonp的实现原理,script标签的异步加载。
util.jsonp = (url, onsuccess, onerror, charset) => {
let callbackName = url.getName('tt_player')
window[callbackName] = function () {
if (onsuccess && onsuccess instanceof Function) {
onsuccess(arguments[0])
}
}
let script = util.createScript(url + '&callback=' + callbackName, charset)
script.onload = script.onreadystatechange = function () {
if (!script.readyState || /loaded|complete/.test(script.readyState)) {
script.onload = script.onreadystatechange = null
// 移除该script的DOM对象
if(script.parentNode) {
script.parentNode.removeChild(script)
}
// 删除函数或变量
window[callbackName] = null
}
}
script.onerror = function () {
if (onerror && onerror instanceof Function) {
onerror()
}
}
document.getElementsByTagName('head')[0].appendChild(script)
}
util.createScript = (url, charset) => {
let script = document.createElement('script')
script.setAttribute('type', 'text/javascript')
charset && script.setAttribute('charset', charset)
script.setAttribute('src, url)
script.async = true
return script
}
- 浏览器用加载script标签的方式,给服务端发请求(回调名jsonp等)。创建一个json全局函数
- 服务器返回js块内容(回调名和代码),调用jsonp函数就能运行了。
<script src="http://www.abc.com/?data=name&callback=jsonp" charset="utf-8"></script>
<script>
jsonp({data: {}})
</script>
Hash
利用hash,场景是当前页面A,通过iframe或frame嵌入了跨域的页面B
// 在A中伪代码如下
var B = document.getElementByTagName('iframe')
B.src = B.src + '#' + 'data'
window.onhashchange = function () {
var data = window.location.hash
}
postMessage
// 窗口A(http://A.com)向跨域的窗口B(http://B.com)发送信息
Bwindow.postMessage('data', 'http://B.com') // B窗口下的window
// 在窗口B中监听
window.addEventListener('message', function(event) {
console.log(event.origin) // http://A.com
console.log(event.source) // Awinodw
console.log(event.data) // data!
}, false)
WebSocket
var ws = new WebSocket('wss://echo.websocket.org') // ws或者wss(加密),后面指向服务器的地址
ws.onopen = function (evt) {
console.log('Connection open...')
ws.send('Hello WebSocket!')
}
ws.onmessage = function (evt) {
console.log('Received Message: ' + evt.data)
wx.close()
}
ws.onclose = function (evt) {
console.log('Connection closed')
}
CORS
参考资料: http://www.ruanyifeng.com/blog/2016/04/cors.html
var ws = new WebSocket('wss://echo.websocket.org') // ws或者wss(加密),后面指向服务器的地址
fetch('/some/url', {
method: 'get'
}).then(res => {}).catch(err => {})