跨域问题的产生,怎么解决它?
由于浏览器的 同源策略,在出现 域名、端口、协议有一种不一致时,就会出现跨域,属于浏览器的一种安全限制。
解决跨域问题有很多种方式,常用的就是以下几种:
jsonp 跨域:动态创建script,再请求一个带参网址实现跨域通信.缺点就是只能实现 get 一种请求
1 function jsonp(url, jsonpCallback, success) { 2 let script = document.createElement('script') 3 script.src = url 4 script.async = true 5 script.type = 'text/javascript' 6 window[jsonpCallback] = function(data) { 7 success && success(data) 8 } 9 document.body.appendChild(script) 10 } 11 jsonp('http://xxx', 'callback', function(value) { 12 console.log(value) 13 })
document.domain + iframe跨域:两个页面都通过js强制设置document.domain为基础主域,就实现了同域.但是仅限主域相同,子域不同的跨域应用场景
跨域资源共享CORS: 只服务端设置Access-Control-Allow-Origin即可,前端无须设置,若要带cookie请求:前后端都需要设置 CORS 需要浏览器和后端同时支持。IE 8 和 9 需要通过 XDomainRequest 来实现。 浏览器会自动进行 CORS 通信,实现 CORS 通信的关键是后端。只要后端实现了 CORS,就实现了跨域。 服务端设置 Access-Control-Allow-Origin 就可以开启 CORS。 该属性表示哪些域名可以访问资源,如果设置通配符则表示所有网站都可以访问资源。
nginx反向代理接口跨域:同源策略是浏览器的安全策略,不是HTTP协议的一部分。服务器端调用HTTP接口只是使用HTTP协议,不会执行JS脚本,不需要同源策略,也就不存在跨越问题
postMessage :这种方式通常用于获取嵌入页面中的第三方页面数据。一个页面发送消息,另一个页面判断来源并接收消息
1 // 发送消息端 2 window.parent.postMessage('message', 'http://test.com') 3 // 接收消息端 4 var mc = new MessageChannel() 5 mc.addEventListener('message', event => { 6 var origin = event.origin || event.originalEvent.origin 7 if (origin === 'http://test.com') { 8 console.log('验证通过') 9 } 10 })
WebSocket协议跨域:
1 var ws = new WebSocket("wss://echo.websocket.org"); 2 ws.onopen = function(evt) { 3 console.log("Connection open ..."); 4 ws.send("Hello WebSockets!"); 5 }; 6 ws.onmessage = function(evt) { 7 console.log( "Received Message: " + evt.data); 8 ws.close(); 9 }; 10 ws.onclose = function(evt) { 11 console.log("Connection closed."); 12 }