跨域通信的几种方式

跨域通信的几种方式

  • 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
}
  1. 浏览器用加载script标签的方式,给服务端发请求(回调名jsonp等)。创建一个json全局函数
  2. 服务器返回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 => {})

 

posted @ 2019-11-28 20:15  lilicat  阅读(506)  评论(0编辑  收藏  举报