前端跨域的解决方案?

简介: 前端跨域的解决方案?

一、什么是跨域?

  在前端领域中,跨域是指浏览器允许向服务器发送跨域请求,从而克服Ajax只能同源使用的限制。

什么是同源策略?

同源策略是一种约定,由Netscape公司1995年引入浏览器,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,浏览器很容易受到XSS、CSFR等攻击。所谓同源是指"协议+域名+端口"三者相同,即便两个不同的域名指向同一个ip地址,也非同源。


 同源策略限制以下几种行为:

  • Cookie、LocalStorage 和 IndexDB 无法读取
  • DOM和JS对象无法获得
  • AJAX 请求不能发送

二、常见的跨域场景

image.png

三、9种跨域解决方案

1、JSONP跨域

  jsonp的原理就是利用标签没有跨域限制,通过</code>标签src属性,发送带有callback参数的GET请求,</span></span><span style="color: #1C1F21;"><span style="background-color: #F8FAFC;">服务端将接口返回数据拼凑到callback函数中,返回给浏览器,浏览器解析执行,从而前端拿到callback函数返回的数据。<br /><br />1)原生JS实现:</span></span><span style="color: #1C1F21;"><span style="background-color: #F8FAFC;"><code></code></span></span></div><div data-card-type="block" data-ready-card="codeblock" data-card-value="data:%7B%22mode%22%3A%22plain%22%2C%22code%22%3A%22%20%3Cscript%3E%5Cn%20%20%20%20var%20script%20%3D%20document.createElement('script')%3B%5Cn%20%20%20%20script.type%20%3D%20'text%2Fjavascript'%3B%5Cn%20%5Cn%20%20%20%20%2F%2F%20%E4%BC%A0%E5%8F%82%E4%B8%80%E4%B8%AA%E5%9B%9E%E8%B0%83%E5%87%BD%E6%95%B0%E5%90%8D%E7%BB%99%E5%90%8E%E7%AB%AF%EF%BC%8C%E6%96%B9%E4%BE%BF%E5%90%8E%E7%AB%AF%E8%BF%94%E5%9B%9E%E6%97%B6%E6%89%A7%E8%A1%8C%E8%BF%99%E4%B8%AA%E5%9C%A8%E5%89%8D%E7%AB%AF%E5%AE%9A%E4%B9%89%E7%9A%84%E5%9B%9E%E8%B0%83%E5%87%BD%E6%95%B0%5Cn%20%20%20%20script.src%20%3D%20'http%3A%2F%2Fwww.domain2.com%3A8080%2Flogin%3Fuser%3Dadmin%26callback%3DhandleCallback'%3B%5Cn%20%20%20%20document.head.appendChild(script)%3B%5Cn%20%5Cn%20%20%20%20%2F%2F%20%E5%9B%9E%E8%B0%83%E6%89%A7%E8%A1%8C%E5%87%BD%E6%95%B0%5Cn%20%20%20%20function%20handleCallback(res)%20%7B%5Cn%20%20%20%20%20%20%20%20alert(JSON.stringify(res))%3B%5Cn%20%20%20%20%7D%5Cn%20%3C%2Fscript%3E%22%2C%22id%22%3A%22sm5F1%22%7D"></div><div><span style="color: #1C1F21;"><span style="background-color: #F8FAFC;">服务端返回如下(返回时即执行全局函数):</span></span></div><div data-card-type="block" data-ready-card="codeblock" data-card-value="data:%7B%22mode%22%3A%22plain%22%2C%22code%22%3A%22handleCallback(%7B%5C%22success%5C%22%3A%20true%2C%20%5C%22user%5C%22%3A%20%5C%22admin%5C%22%7D)%22%2C%22id%22%3A%22J5p8H%22%7D"></div><div><span style="color: #1C1F21;"><span style="background-color: #F8FAFC;">2)jquery Ajax实现:</span></span></div><div data-card-type="block" data-ready-card="codeblock" data-card-value="data:%7B%22mode%22%3A%22plain%22%2C%22code%22%3A%22%24.ajax(%7B%5Cn%20%20%20%20url%3A%20'http%3A%2F%2Fwww.domain2.com%3A8080%2Flogin'%2C%5Cn%20%20%20%20type%3A%20'get'%2C%5Cn%20%20%20%20dataType%3A%20'jsonp'%2C%20%20%2F%2F%20%E8%AF%B7%E6%B1%82%E6%96%B9%E5%BC%8F%E4%B8%BAjsonp%5Cn%20%20%20%20jsonpCallback%3A%20%5C%22handleCallback%5C%22%2C%20%20%2F%2F%20%E8%87%AA%E5%AE%9A%E4%B9%89%E5%9B%9E%E8%B0%83%E5%87%BD%E6%95%B0%E5%90%8D%5Cn%20%20%20%20data%3A%20%7B%7D%5Cn%7D)%3B%22%2C%22id%22%3A%221FWwu%22%7D"></div><div><span class="lake-fontsize-12" style="color: #1C1F21; background-color: #F8FAFC;">3)Vue axios实现:</span></div><div data-card-type="block" data-ready-card="codeblock" data-card-value="data:%7B%22mode%22%3A%22plain%22%2C%22code%22%3A%22this.%24http%20%3D%20axios%3B%5Cnthis.%24http.jsonp('http%3A%2F%2Fwww.domain2.com%3A8080%2Flogin'%2C%20%7B%5Cn%20%20%20%20params%3A%20%7B%7D%2C%5Cn%20%20%20%20jsonp%3A%20'handleCallback'%5Cn%7D).then((res)%20%3D%3E%20%7B%5Cn%20%20%20%20console.log(res)%3B%20%5Cn%7D)%22%2C%22heightLimit%22%3Atrue%2C%22margin%22%3Atrue%2C%22id%22%3A%22fhRyZ%22%7D"></div><div><span style="color: #1C1F21;"><span style="background-color: #F8FAFC;">后端node.js代码:</span></span></div><blockquote><div><span style="color: #1C1F21;"><span style="background-color: #F8FAFC;">jsonp的缺点:只能发送get一种请求。</span></span></div></blockquote><h3 id="2cIzX"><a name="t5"></a><span style="color: #1C1F21;"><span style="background-color: #F8FAFC;">2、跨域资源共享(CORS)</span></span></h3><div><span class="lake-fontsize-12" style="color: #1C1F21; background-color: #F8FAFC;"> </span><strong>CORS</strong><span class="lake-fontsize-12" style="color: #1C1F21; background-color: #F8FAFC;">是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。</span></div><div><span class="lake-fontsize-12" style="color: #1C1F21; background-color: #F8FAFC;">它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。</span></div><div><span class="lake-fontsize-12" style="color: #1C1F21; background-color: #F8FAFC;">CORS需要浏览器和服务器同时支持。</span><span style="color: #1C1F21;"><span style="background-color: #F8FAFC;">目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。<br /><br />  浏览器将CORS跨域请求分为简单请求和非简单请求。<br /><br />  只要同时满足一下两个条件,就属于简单请求<br /><br />(1)使用下列方法之一:</span></span></div><ul><li><span style="color: #1C1F21;"><span style="background-color: #F8FAFC;">head</span></span></li><li><span style="color: #1C1F21;"><span style="background-color: #F8FAFC;">get</span></span></li><li><span style="color: #1C1F21;"><span style="background-color: #F8FAFC;">post</span></span></li></ul><div><span style="color: #1C1F21;"><span style="background-color: #F8FAFC;">(2)请求的Heder是</span></span></div><ul><li><span style="color: #1C1F21;"><span style="background-color: #F8FAFC;">Accept</span></span></li><li><span style="color: #1C1F21;"><span style="background-color: #F8FAFC;">Accept-Language</span></span></li><li><span style="color: #1C1F21;"><span style="background-color: #F8FAFC;">Content-Language</span></span></li><li><span style="color: #1C1F21;"><span style="background-color: #F8FAFC;">Content-Type: 只限于三个值:application/x-www-form-urlencoded、multipart/form-data、text/plain</span></span></li></ul><div><span style="color: #1C1F21;"><span style="background-color: #F8FAFC;">不同时满足上面的两个条件,就属于非简单请求。浏览器对这两种的处理,是不一样的。</span></span></div><h3 id="ceruZ"><a name="t6"></a><span style="color: #1C1F21;"><span style="background-color: #F8FAFC;">简单请求</span></span></h3><div><span style="color: #1C1F21;"><span style="background-color: #F8FAFC;">  对于简单请求,浏览器直接发出CORS请求。具体来说,就是在头信息之中,增加一个Origin字段。</span></span></div><div data-card-type="block" data-ready-card="codeblock" data-card-value="data:%7B%22mode%22%3A%22plain%22%2C%22code%22%3A%22GET%20%2Fcors%20HTTP%2F1.1%5CnOrigin%3A%20http%3A%2F%2Fapi.bob.com%5CnHost%3A%20api.alice.com%5CnAccept-Language%3A%20en-US%5CnConnection%3A%20keep-alive%5CnUser-Agent%3A%20Mozilla%2F5.0...%22%2C%22heightLimit%22%3Atrue%2C%22margin%22%3Atrue%2C%22id%22%3A%22LTOap%22%7D"></div><div><span style="color: #1C1F21;"><span style="background-color: #F8FAFC;">上面的头信息中,Origin字段用来说明,本次请求来自哪个源(协议 + 域名 + 端口)。服务器根据这个值,决定是否同意这次请求。</span></span></div><div><span style="color: #1C1F21;"><span style="background-color: #F8FAFC;">CORS请求设置的响应头字段,都以 Access-Control-开头:</span></span></div><div><strong>1)Access-Control-Allow-Origin</strong><span class="lake-fontsize-12" style="color: #1C1F21; background-color: #F8FAFC;">:必选</span></div><div><br /></div><div><span class="lake-fontsize-12" style="color: #1C1F21; background-color: #F8FAFC;">  它的值要么是请求时Origin字段的值,要么是一个*,表示接受任意域名的请求。</span></div><div><br /></div><div><strong>2)Access-Control-Allow-Credentials</strong><span class="lake-fontsize-12" style="color: #1C1F21; background-color: #F8FAFC;">:可选</span></div><div><span style="color: #1C1F21;"><span style="background-color: #F8FAFC;"></span></span><br /></div><div><span class="lake-fontsize-12" style="color: #1C1F21; background-color: #F8FAFC;">  它的值是一个布尔值,表示是否允许发送Cookie。默认情况下,Cookie不包括在CORS请求之中。设为true,即表示服务器明确许可,Cookie可以包含在请求中,一起发给服务器。这个值也只能设为true,如果服务器不要浏览器发送Cookie,删除该字段即可。</span></div><div><span style="color: #1C1F21;"><span style="background-color: #F8FAFC;"></span></span><br /></div><div><strong>3)Access-Control-Expose-Headers</strong><span class="lake-fontsize-12" style="color: #1C1F21; background-color: #F8FAFC;">:可选</span></div><div><span class="lake-fontsize-12" style="color: #1C1F21; background-color: #F8FAFC;">CORS请求时,XMLHttpRequest对象的getResponseHeader()方法只能拿到6个基本字段:Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma。如果想拿到其他字段,</span><span style="color: #1C1F21;"><span style="background-color: #F8FAFC;">就必须在Access-Control-Expose-Headers里面指定。上面的例子指定,getResponseHeader(‘FooBar’)可以返回FooBar字段的值。</span></span></div><h3 id="PNVrg"><a name="t7"></a><span style="color: #1C1F21;"><span style="background-color: #F8FAFC;">非简单请求</span></span></h3><div><span class="lake-fontsize-12" style="color: #1C1F21; background-color: #F8FAFC;"> 非简单请求是那种对服务器有特殊要求的请求,比如请求方法是PUT或DELETE,或者Content-Type字段的类型是application/json。非简单请求的CORS请求,会在正式通信之前,增加一次HTTP查询请求,</span><span style="color: #1C1F21;"><span style="background-color: #F8FAFC;">称为"预检"请求(preflight)。</span></span></div><div><span style="color: #1C1F21;"><span style="background-color: #F8FAFC;">预检请求</span></span></div><div><span style="color: #1C1F21;"><span style="background-color: #F8FAFC;">  预检"请求用的请求方法是OPTIONS,表示这个请求是用来询问的。请求头信息里面,关键字段是Origin,表示请求来自哪个源。除了Origin字段,"预检"请求的头信息包括两个特殊字段。</span></span></div><div data-card-type="block" data-ready-card="codeblock" data-card-value="data:%7B%22mode%22%3A%22plain%22%2C%22code%22%3A%22OPTIONS%20%2Fcors%20HTTP%2F1.1%5CnOrigin%3A%20http%3A%2F%2Fapi.bob.com%5CnAccess-Control-Request-Method%3A%20PUT%5CnAccess-Control-Request-Headers%3A%20X-Custom-Header%5CnHost%3A%20api.alice.com%5CnAccept-Language%3A%20en-US%5CnConnection%3A%20keep-alive%5CnUser-Agent%3A%20Mozilla%2F5.0..%22%2C%22heightLimit%22%3Atrue%2C%22margin%22%3Atrue%2C%22id%22%3A%22Li1fw%22%7D"></div><div><strong>1)Access-Control-Request-Method</strong><span class="lake-fontsize-12" style="color: #1C1F21; background-color: #F8FAFC;">:必选</span></div><div><br /></div><div><span class="lake-fontsize-12" style="color: #1C1F21; background-color: #F8FAFC;">  用来列出浏览器的CORS请求会用到哪些HTTP方法,上例是PUT。</span></div><div><br /></div><div><strong>2)Access-Control-Request-Headers</strong><span class="lake-fontsize-12" style="color: #1C1F21; background-color: #F8FAFC;">:可选</span></div><div><span style="color: #1C1F21;"><span style="background-color: #F8FAFC;"><br />  该字段是一个逗号分隔的字符串,指定浏览器CORS请求会额外发送的头信息字段,上例是X-Custom-Header。</span></span></div><div><span style="color: #1C1F21;"><span style="background-color: #F8FAFC;">预检请求的回应</span></span></div><div><span class="lake-fontsize-12" style="color: #1C1F21; background-color: #F8FAFC;"> 服务器收到"预检"请求以后,检查了Origin、Access-Control-Request-Method和Access-Control-Request-Headers字段以后,确认允许跨源请求,就可以做出回应。</span></div><div><span class="lake-fontsize-12" style="color: #1C1F21; background-color: #F8FAFC;"> HTTP回应中,除了关键的是Access-Control-Allow-Origin字段,其他CORS相关字段如下:</span></div><div><br /></div><div><strong>1)Access-Control-Allow-Methods</strong><span class="lake-fontsize-12" style="color: #1C1F21; background-color: #F8FAFC;">:必选</span></div><div><span class="lake-fontsize-12" style="color: #1C1F21; background-color: #F8FAFC;">它的值是逗号分隔的一个字符串,表明服务器支持的所有跨域请求的方法。注意,返回的是所有支持的方法,而不单是浏览器请求的那个方法。这是为了避免多次"预检"请求。</span></div><div><br /></div><div><strong>2)Access-Control-Allow-Headers</strong></div><div><span style="color: #1C1F21;"><span style="background-color: #F8FAFC;"></span></span><br /></div><div><span class="lake-fontsize-12" style="color: #1C1F21; background-color: #F8FAFC;">  如果浏览器请求包括Access-Control-Request-Headers字段,则Access-Control-Allow-Headers字段是必需的。它也是一个逗号分隔的字符串,表明服务器支持的所有头信息字段,不限于浏览器在"预检"中请求的字段。</span></div><div><span style="color: #1C1F21;"><span style="background-color: #F8FAFC;"></span></span><br /></div><div><strong>3)Access-Control-Allow-Credentials</strong><span class="lake-fontsize-12" style="color: #1C1F21; background-color: #F8FAFC;">:可选</span></div><div><br /></div><div><span class="lake-fontsize-12" style="color: #1C1F21; background-color: #F8FAFC;">  该字段与简单请求时的含义相同。</span></div><div><br /></div><div><strong>4)Access-Control-Max-Age</strong><span class="lake-fontsize-12" style="color: #1C1F21; background-color: #F8FAFC;">:可选</span></div><div><span style="color: #1C1F21;"><span style="background-color: #F8FAFC;"><br />  用来指定本次预检请求的有效期,单位为秒。</span></span></div><h3 id="vLxxx"><a name="t8"></a><span style="color: #1C1F21;"><span style="background-color: #F8FAFC;">CORS跨域示例</span></span></h3><div><span style="color: #1C1F21;"><span style="background-color: #F8FAFC;"><strong>1)前端设置</strong>:</span></span></div><ul><li><span style="color: #1C1F21;"><span style="background-color: #F8FAFC;">原生ajax:</span></span></li></ul><div data-card-type="block" data-ready-card="codeblock" data-card-value="data:%7B%22mode%22%3A%22plain%22%2C%22code%22%3A%22var%20xhr%20%3D%20new%20XMLHttpRequest()%3B%20%2F%2F%20IE8%2F9%E9%9C%80%E7%94%A8window.XDomainRequest%E5%85%BC%E5%AE%B9%5Cn%20%5Cn%2F%2F%20%E5%89%8D%E7%AB%AF%E8%AE%BE%E7%BD%AE%E6%98%AF%E5%90%A6%E5%B8%A6cookie%5Cnxhr.withCredentials%20%3D%20true%3B%5Cn%20%5Cnxhr.open('post'%2C%20'http%3A%2F%2Fwww.domain2.com%3A8080%2Flogin'%2C%20true)%3B%5Cnxhr.setRequestHeader('Content-Type'%2C%20'application%2Fx-www-form-urlencoded')%3B%5Cnxhr.send('user%3Dadmin')%3B%5Cn%20%5Cnxhr.onreadystatechange%20%3D%20function()%20%7B%5Cn%20%20%20%20if%20(xhr.readyState%20%3D%3D%204%20%26%26%20xhr.status%20%3D%3D%20200)%20%7B%5Cn%20%20%20%20%20%20%20%20alert(xhr.responseText)%3B%5Cn%20%20%20%20%7D%5Cn%7D%3B%5Cnjquery%20ajax%EF%BC%9A%22%2C%22heightLimit%22%3Atrue%2C%22margin%22%3Atrue%2C%22id%22%3A%2203NC3%22%7D"></div><div data-card-type="block" data-ready-card="codeblock" data-card-value="data:%7B%22mode%22%3A%22plain%22%2C%22code%22%3A%22%24.ajax(%7B%5Cn%20%20%20%20...%5Cn%20%20%20xhrFields%3A%20%7B%5Cn%20%20%20%20%20%20%20withCredentials%3A%20true%20%20%20%20%2F%2F%20%E5%89%8D%E7%AB%AF%E8%AE%BE%E7%BD%AE%E6%98%AF%E5%90%A6%E5%B8%A6cookie%5Cn%20%20%20%7D%2C%5Cn%20%20%20crossDomain%3A%20true%2C%20%20%20%2F%2F%20%E4%BC%9A%E8%AE%A9%E8%AF%B7%E6%B1%82%E5%A4%B4%E4%B8%AD%E5%8C%85%E5%90%AB%E8%B7%A8%E5%9F%9F%E7%9A%84%E9%A2%9D%E5%A4%96%E4%BF%A1%E6%81%AF%EF%BC%8C%E4%BD%86%E4%B8%8D%E4%BC%9A%E5%90%ABcookie%5Cn%20%20%20%20...%5Cn%7D)%3B%22%2C%22heightLimit%22%3Atrue%2C%22margin%22%3Atrue%2C%22id%22%3A%22KoFEE%22%7D"></div><ul><li><span style="color: #1C1F21;"><span style="background-color: #F8FAFC;"><strong>2)服务端设置</strong>:</span></span><br /></li><li><span style="color: #1C1F21;"><span style="background-color: #F8FAFC;">nodejs代码</span></span></li></ul><div data-card-type="block" data-ready-card="codeblock" data-card-value="data:%7B%22mode%22%3A%22plain%22%2C%22code%22%3A%22var%20http%20%3D%20require('http')%3B%5Cnvar%20server%20%3D%20http.createServer()%3B%5Cnvar%20qs%20%3D%20require('querystring')%3B%5Cn%20%5Cnserver.on('request'%2C%20function(req%2C%20res)%20%7B%5Cn%20%20%20%20var%20postData%20%3D%20''%3B%5Cn%20%5Cn%20%20%20%20%2F%2F%20%E6%95%B0%E6%8D%AE%E5%9D%97%E6%8E%A5%E6%94%B6%E4%B8%AD%5Cn%20%20%20%20req.addListener('data'%2C%20function(chunk)%20%7B%5Cn%20%20%20%20%20%20%20%20postData%20%2B%3D%20chunk%3B%5Cn%20%20%20%20%7D)%3B%5Cn%20%5Cn%20%20%20%20%2F%2F%20%E6%95%B0%E6%8D%AE%E6%8E%A5%E6%94%B6%E5%AE%8C%E6%AF%95%5Cn%20%20%20%20req.addListener('end'%2C%20function()%20%7B%5Cn%20%20%20%20%20%20%20%20postData%20%3D%20qs.parse(postData)%3B%5Cn%20%5Cn%20%20%20%20%20%20%20%20%2F%2F%20%E8%B7%A8%E5%9F%9F%E5%90%8E%E5%8F%B0%E8%AE%BE%E7%BD%AE%5Cn%20%20%20%20%20%20%20%20res.writeHead(200%2C%20%7B%5Cn%20%20%20%20%20%20%20%20%20%20%20%20'Access-Control-Allow-Credentials'%3A%20'true'%2C%20%20%20%20%20%2F%2F%20%E5%90%8E%E7%AB%AF%E5%85%81%E8%AE%B8%E5%8F%91%E9%80%81Cookie%5Cn%20%20%20%20%20%20%20%20%20%20%20%20'Access-Control-Allow-Origin'%3A%20'http%3A%2F%2Fwww.domain1.com'%2C%20%20%20%20%2F%2F%20%E5%85%81%E8%AE%B8%E8%AE%BF%E9%97%AE%E7%9A%84%E5%9F%9F%EF%BC%88%E5%8D%8F%E8%AE%AE%2B%E5%9F%9F%E5%90%8D%2B%E7%AB%AF%E5%8F%A3%EF%BC%89%5Cn%20%20%20%20%20%20%20%20%20%20%20%20%2F*%20%5Cn%20%20%20%20%20%20%20%20%20%20%20%20%20*%20%E6%AD%A4%E5%A4%84%E8%AE%BE%E7%BD%AE%E7%9A%84cookie%E8%BF%98%E6%98%AFdomain2%E7%9A%84%E8%80%8C%E9%9D%9Edomain1%EF%BC%8C%E5%9B%A0%E4%B8%BA%E5%90%8E%E7%AB%AF%E4%B9%9F%E4%B8%8D%E8%83%BD%E8%B7%A8%E5%9F%9F%E5%86%99cookie(nginx%E5%8F%8D%E5%90%91%E4%BB%A3%E7%90%86%E5%8F%AF%E4%BB%A5%E5%AE%9E%E7%8E%B0)%EF%BC%8C%5Cn%20%20%20%20%20%20%20%20%20%20%20%20%20*%20%E4%BD%86%E5%8F%AA%E8%A6%81domain2%E4%B8%AD%E5%86%99%E5%85%A5%E4%B8%80%E6%AC%A1cookie%E8%AE%A4%E8%AF%81%EF%BC%8C%E5%90%8E%E9%9D%A2%E7%9A%84%E8%B7%A8%E5%9F%9F%E6%8E%A5%E5%8F%A3%E9%83%BD%E8%83%BD%E4%BB%8Edomain2%E4%B8%AD%E8%8E%B7%E5%8F%96cookie%EF%BC%8C%E4%BB%8E%E8%80%8C%E5%AE%9E%E7%8E%B0%E6%89%80%E6%9C%89%E7%9A%84%E6%8E%A5%E5%8F%A3%E9%83%BD%E8%83%BD%E8%B7%A8%E5%9F%9F%E8%AE%BF%E9%97%AE%5Cn%20%20%20%20%20%20%20%20%20%20%20%20%20*%2F%5Cn%20%20%20%20%20%20%20%20%20%20%20%20'Set-Cookie'%3A%20'l%3Da123456%3BPath%3D%2F%3BDomain%3Dwww.domain2.com%3BHttpOnly'%20%20%2F%2F%20HttpOnly%E7%9A%84%E4%BD%9C%E7%94%A8%E6%98%AF%E8%AE%A9js%E6%97%A0%E6%B3%95%E8%AF%BB%E5%8F%96cookie%5Cn%20%20%20%20%20%20%20%20%7D)%3B%5Cn%20%5Cn%20%20%20%20%20%20%20%20res.write(JSON.stringify(postData))%3B%5Cn%20%20%20%20%20%20%20%20res.end()%3B%5Cn%20%20%20%20%7D)%3B%5Cn%7D)%3B%5Cn%20%5Cnserver.listen('8080')%3B%5Cnconsole.log('Server%20is%20running%20at%20port%208080...')%3B%22%2C%22heightLimit%22%3Atrue%2C%22margin%22%3Atrue%2C%22id%22%3A%226su97%22%7D"></div><h3 id="ZGIGz"><span style="color: #1C1F21;"><span style="background-color: #F8FAFC;">3、nginx代理跨域</span></span></h3><div><span style="color: #1C1F21;"><span style="background-color: #F8FAFC;">  nginx代理跨域,实质和CORS跨域原理一样,通过配置文件设置请求响应头<span style="color: #FF502C;">Access-Control-Allow-Origin</span>…等字段。</span></span></div><div><span style="color: #1C1F21;"><span style="background-color: #F8FAFC;">1)nginx配置解决iconfont跨域</span></span></div><div><span class="lake-fontsize-12" style="color: #1C1F21; background-color: #F8FAFC;">浏览器跨域访问js、css、img等常规静态资源被同源策略许可,但iconfont字体文件(eot|otf|ttf|woff|svg)例外,此时可在nginx的静态资源服务器中加入以下配置。</span></div><div data-card-type="block" data-ready-card="codeblock" data-card-value="data:%7B%22mode%22%3A%22plain%22%2C%22code%22%3A%22location%20%2F%20%7B%5Cn%20%20add_header%20Access-Control-Allow-Origin%20*%3B%5Cn%7D%22%2C%22heightLimit%22%3Atrue%2C%22margin%22%3Atrue%2C%22id%22%3A%22LZenQ%22%7D"></div><div><span style="color: #1C1F21;"><span style="background-color: #F8FAFC;">2)nginx反向代理接口跨域</span></span></div><blockquote><div><span style="color: #1C1F21;"><span style="background-color: #F8FAFC;">跨域问题:同源策略仅是针对浏览器的安全策略。服务器端调用HTTP接口只是使用HTTP协议,不需要同源策略,也就不存在跨域问题。</span></span></div></blockquote><div><span class="lake-fontsize-12" style="color: #1C1F21; background-color: #F8FAFC;">实现思路:通过Nginx配置一个代理服务器域名与domain1相同,端口不同)做跳板机,反向代理访问domain2接口,并且可以顺便修改cookie中domain信息,方便当前域cookie写入,实现跨域访问。</span></div><div><br /></div><div><span class="lake-fontsize-12" style="color: #1C1F21; background-color: #F8FAFC;">nginx具体配置:</span></div><div data-card-type="block" data-ready-card="codeblock" data-card-value="data:%7B%22mode%22%3A%22plain%22%2C%22code%22%3A%22%23proxy%E6%9C%8D%E5%8A%A1%E5%99%A8%5Cnserver%20%7B%5Cn%20%20%20%20listen%20%20%20%20%20%20%2081%3B%5Cn%20%20%20%20server_name%20%20www.domain1.com%3B%5Cn%20%5Cn%20%20%20%20location%20%2F%20%7B%5Cn%20%20%20%20%20%20%20%20proxy_pass%20%20%20http%3A%2F%2Fwww.domain2.com%3A8080%3B%20%20%23%E5%8F%8D%E5%90%91%E4%BB%A3%E7%90%86%5Cn%20%20%20%20%20%20%20%20proxy_cookie_domain%20www.domain2.com%20www.domain1.com%3B%20%23%E4%BF%AE%E6%94%B9cookie%E9%87%8C%E5%9F%9F%E5%90%8D%5Cn%20%20%20%20%20%20%20%20index%20%20index.html%20index.htm%3B%5Cn%20%5Cn%20%20%20%20%20%20%20%20%23%20%E5%BD%93%E7%94%A8webpack-dev-server%E7%AD%89%E4%B8%AD%E9%97%B4%E4%BB%B6%E4%BB%A3%E7%90%86%E6%8E%A5%E5%8F%A3%E8%AE%BF%E9%97%AEnignx%E6%97%B6%EF%BC%8C%E6%AD%A4%E6%97%B6%E6%97%A0%E6%B5%8F%E8%A7%88%E5%99%A8%E5%8F%82%E4%B8%8E%EF%BC%8C%E6%95%85%E6%B2%A1%E6%9C%89%E5%90%8C%E6%BA%90%E9%99%90%E5%88%B6%EF%BC%8C%E4%B8%8B%E9%9D%A2%E7%9A%84%E8%B7%A8%E5%9F%9F%E9%85%8D%E7%BD%AE%E5%8F%AF%E4%B8%8D%E5%90%AF%E7%94%A8%5Cn%20%20%20%20%20%20%20%20add_header%20Access-Control-Allow-Origin%20http%3A%2F%2Fwww.domain1.com%3B%20%20%23%E5%BD%93%E5%89%8D%E7%AB%AF%E5%8F%AA%E8%B7%A8%E5%9F%9F%E4%B8%8D%E5%B8%A6cookie%E6%97%B6%EF%BC%8C%E5%8F%AF%E4%B8%BA*%5Cn%20%20%20%20%20%20%20%20add_header%20Access-Control-Allow-Credentials%20true%3B%5Cn%20%20%20%20%7D%5Cn%7D%22%2C%22heightLimit%22%3Atrue%2C%22margin%22%3Atrue%2C%22id%22%3A%22t4BWm%22%7D"></div><h3 id="ZszYr"><span style="color: #1C1F21;"><span style="background-color: #F8FAFC;">4、nodejs中间件代理跨域</span></span></h3><div><span style="color: #1C1F21;"><span style="background-color: #F8FAFC;">  node中间件实现跨域代理,原理大致与nginx相同,都是通过启一个代理服务器,实现数据的转发,也可以通过设置cookieDomainRewrite参数修改</span></span><span style="color: #1C1F21;"><span style="background-color: #F8FAFC;">响应头中cookie中域名,实现当前域的cookie写入,方便接口登录认证。<br /><br /><strong>1)非vue框架的跨域</strong><br /><br />  使用node + express + http-proxy-middleware搭建一个proxy服务器。</span></span></div><ul><li><span style="color: #1C1F21;"><span style="background-color: #F8FAFC;">前端代码:</span></span></li></ul><div data-card-type="block" data-ready-card="codeblock" data-card-value="data:%7B%22mode%22%3A%22plain%22%2C%22code%22%3A%22var%20xhr%20%3D%20new%20XMLHttpRequest()%3B%5Cn%20%5Cn%2F%2F%20%E5%89%8D%E7%AB%AF%E5%BC%80%E5%85%B3%EF%BC%9A%E6%B5%8F%E8%A7%88%E5%99%A8%E6%98%AF%E5%90%A6%E8%AF%BB%E5%86%99cookie%5Cnxhr.withCredentials%20%3D%20true%3B%5Cn%20%5Cn%2F%2F%20%E8%AE%BF%E9%97%AEhttp-proxy-middleware%E4%BB%A3%E7%90%86%E6%9C%8D%E5%8A%A1%E5%99%A8%5Cnxhr.open('get'%2C%20'http%3A%2F%2Fwww.domain1.com%3A3000%2Flogin%3Fuser%3Dadmin'%2C%20true)%3B%5Cnxhr.send()%3B%22%2C%22heightLimit%22%3Atrue%2C%22margin%22%3Atrue%2C%22id%22%3A%220J2JJ%22%7D"></div><ul><li><span style="color: #1C1F21;"><span style="background-color: #F8FAFC;">中间件服务器代码:</span></span></li></ul><div data-card-type="block" data-ready-card="codeblock" data-card-value="data:%7B%22mode%22%3A%22plain%22%2C%22code%22%3A%22var%20express%20%3D%20require('express')%3B%5Cnvar%20proxy%20%3D%20require('http-proxy-middleware')%3B%5Cnvar%20app%20%3D%20express()%3B%5Cn%20%5Cnapp.use('%2F'%2C%20proxy(%7B%5Cn%20%20%20%20%2F%2F%20%E4%BB%A3%E7%90%86%E8%B7%A8%E5%9F%9F%E7%9B%AE%E6%A0%87%E6%8E%A5%E5%8F%A3%5Cn%20%20%20%20target%3A%20'http%3A%2F%2Fwww.domain2.com%3A8080'%2C%5Cn%20%20%20%20changeOrigin%3A%20true%2C%5Cn%20%5Cn%20%20%20%20%2F%2F%20%E4%BF%AE%E6%94%B9%E5%93%8D%E5%BA%94%E5%A4%B4%E4%BF%A1%E6%81%AF%EF%BC%8C%E5%AE%9E%E7%8E%B0%E8%B7%A8%E5%9F%9F%E5%B9%B6%E5%85%81%E8%AE%B8%E5%B8%A6cookie%5Cn%20%20%20%20onProxyRes%3A%20function(proxyRes%2C%20req%2C%20res)%20%7B%5Cn%20%20%20%20%20%20%20%20res.header('Access-Control-Allow-Origin'%2C%20'http%3A%2F%2Fwww.domain1.com')%3B%5Cn%20%20%20%20%20%20%20%20res.header('Access-Control-Allow-Credentials'%2C%20'true')%3B%5Cn%20%20%20%20%7D%2C%5Cn%20%5Cn%20%20%20%20%2F%2F%20%E4%BF%AE%E6%94%B9%E5%93%8D%E5%BA%94%E4%BF%A1%E6%81%AF%E4%B8%AD%E7%9A%84cookie%E5%9F%9F%E5%90%8D%5Cn%20%20%20%20cookieDomainRewrite%3A%20'www.domain1.com'%20%20%2F%2F%20%E5%8F%AF%E4%BB%A5%E4%B8%BAfalse%EF%BC%8C%E8%A1%A8%E7%A4%BA%E4%B8%8D%E4%BF%AE%E6%94%B9%5Cn%7D))%3B%5Cn%20%5Cnapp.listen(3000)%3B%5Cnconsole.log('Proxy%20server%20is%20listen%20at%20port%203000...')%3B%22%2C%22heightLimit%22%3Atrue%2C%22margin%22%3Atrue%2C%22id%22%3A%22TCkX7%22%7D"></div><div><strong>2)vue框架的跨域</strong></div><div><br /></div><div><span class="lake-fontsize-12" style="color: #1C1F21; background-color: #F8FAFC;">  node + vue + webpack + webpack-dev-server搭建的项目,跨域请求接口,直接修改webpack.config.js配置。开发环境下,</span><span class="lake-fontsize-12" style="color: #1C1F21; background-color: #F8FAFC;">vue渲染服务和接口代理服务都是webpack-dev-server同一个,所以页面与代理接口之间不再跨域。</span></div><div><br /></div><div><span class="lake-fontsize-12" style="color: #1C1F21; background-color: #F8FAFC;">webpack.config.js部分配置:</span></div><div data-card-type="block" data-ready-card="codeblock" data-card-value="data:%7B%22mode%22%3A%22plain%22%2C%22code%22%3A%22module.exports%20%3D%20%7B%5Cn%20%20%20%20entry%3A%20%7B%7D%2C%5Cn%20%20%20%20module%3A%20%7B%7D%2C%5Cn%20%20%20%20...%5Cn%20%20%20%20devServer%3A%20%7B%5Cn%20%20%20%20%20%20%20%20historyApiFallback%3A%20true%2C%5Cn%20%20%20%20%20%20%20%20proxy%3A%20%5B%7B%5Cn%20%20%20%20%20%20%20%20%20%20%20%20context%3A%20'%2Flogin'%2C%5Cn%20%20%20%20%20%20%20%20%20%20%20%20target%3A%20'http%3A%2F%2Fwww.domain2.com%3A8080'%2C%20%20%2F%2F%20%E4%BB%A3%E7%90%86%E8%B7%A8%E5%9F%9F%E7%9B%AE%E6%A0%87%E6%8E%A5%E5%8F%A3%5Cn%20%20%20%20%20%20%20%20%20%20%20%20changeOrigin%3A%20true%2C%5Cn%20%20%20%20%20%20%20%20%20%20%20%20secure%3A%20false%2C%20%20%2F%2F%20%E5%BD%93%E4%BB%A3%E7%90%86%E6%9F%90%E4%BA%9Bhttps%E6%9C%8D%E5%8A%A1%E6%8A%A5%E9%94%99%E6%97%B6%E7%94%A8%5Cn%20%20%20%20%20%20%20%20%20%20%20%20cookieDomainRewrite%3A%20'www.domain1.com'%20%20%2F%2F%20%E5%8F%AF%E4%BB%A5%E4%B8%BAfalse%EF%BC%8C%E8%A1%A8%E7%A4%BA%E4%B8%8D%E4%BF%AE%E6%94%B9%5Cn%20%20%20%20%20%20%20%20%7D%5D%2C%5Cn%20%20%20%20%20%20%20%20noInfo%3A%20true%5Cn%20%20%20%20%7D%5Cn%7D%22%2C%22heightLimit%22%3Atrue%2C%22margin%22%3Atrue%2C%22id%22%3A%22dqN2A%22%7D"></div><h3 id="68ccI"><span style="color: #1C1F21;"><span style="background-color: #F8FAFC;">5、document.domain + iframe跨域</span></span></h3><div><span style="color: #1C1F21;"><span style="background-color: #F8FAFC;">  此方案仅限主域相同,子域不同的跨域应用场景。实现原理:两个页面都通过js强制设置document.domain为基础主域,就实现了同域。<br /><br />1)父窗口</span></span></div><div data-card-type="block" data-ready-card="codeblock" data-card-value="data:%7B%22mode%22%3A%22plain%22%2C%22code%22%3A%22%3Ciframe%20id%3D%5C%22iframe%5C%22%20src%3D%5C%22http%3A%2F%2Fchild.domain.com%2Fb.html%5C%22%3E%3C%2Fiframe%3E%5Cn%3Cscript%3E%5Cn%20%20%20%20document.domain%20%3D%20'domain.com'%3B%5Cn%20%20%20%20var%20user%20%3D%20'admin'%3B%5Cn%3C%2Fscript%3E%22%2C%22heightLimit%22%3Atrue%2C%22margin%22%3Atrue%2C%22id%22%3A%22mIAkZ%22%7D"></div><div><span class="lake-fontsize-12" style="color: #1C1F21; background-color: #F8FAFC;">2)子窗口 </span></div><div data-card-type="block" data-ready-card="codeblock" data-card-value="data:%7B%22mode%22%3A%22plain%22%2C%22code%22%3A%22%3Cscript%3E%5Cn%20%20%20%20document.domain%20%3D%20'domain.com'%3B%5Cn%20%20%20%20%2F%2F%20%E8%8E%B7%E5%8F%96%E7%88%B6%E7%AA%97%E5%8F%A3%E4%B8%AD%E5%8F%98%E9%87%8F%5Cn%20%20%20%20console.log('get%20js%20data%20from%20parent%20---%3E%20'%20%2B%20window.parent.user)%3B%5Cn%3C%2Fscript%3E%22%2C%22heightLimit%22%3Atrue%2C%22margin%22%3Atrue%2C%22id%22%3A%22WsfQa%22%7D"></div><h3 id="v2jMZ"><span style="color: #1C1F21;"><span style="background-color: #F8FAFC;">6、location.hash + iframe跨域</span></span></h3><div><span style="color: #1C1F21;"><span style="background-color: #F8FAFC;">  实现原理: a欲与b跨域相互通信,通过中间页c来实现。 三个页面,不同域之间利用iframe的location.hash传值,相同域之间直接js访问来通信。</span></span></div><div><span class="lake-fontsize-12" style="color: #1C1F21; background-color: #F8FAFC;">具体实现:A域:a.html -> B域:b.html -> A域:c.html,a与b不同域只能通过hash值单向通信,b与c也不同域也只能单向通信,但c与a同域,所以c可通过parent.parent访问a页面所有对象。</span></div><div><br /></div><div><span class="lake-fontsize-12" style="color: #1C1F21; background-color: #F8FAFC;">1)a.html </span></div><div data-card-type="block" data-ready-card="codeblock" data-card-value="data:%7B%22mode%22%3A%22plain%22%2C%22code%22%3A%22%3Ciframe%20id%3D%5C%22iframe%5C%22%20src%3D%5C%22http%3A%2F%2Fwww.domain2.com%2Fb.html%5C%22%20style%3D%5C%22display%3Anone%3B%5C%22%3E%3C%2Fiframe%3E%5Cn%3Cscript%3E%5Cn%20%20%20%20var%20iframe%20%3D%20document.getElementById('iframe')%3B%5Cn%20%5Cn%20%20%20%20%2F%2F%20%E5%90%91b.html%E4%BC%A0hash%E5%80%BC%5Cn%20%20%20%20setTimeout(function()%20%7B%5Cn%20%20%20%20%20%20%20%20iframe.src%20%3D%20iframe.src%20%2B%20'%23user%3Dadmin'%3B%5Cn%20%20%20%20%7D%2C%201000)%3B%5Cn%20%20%20%20%5Cn%20%20%20%20%2F%2F%20%E5%BC%80%E6%94%BE%E7%BB%99%E5%90%8C%E5%9F%9Fc.html%E7%9A%84%E5%9B%9E%E8%B0%83%E6%96%B9%E6%B3%95%5Cn%20%20%20%20function%20onCallback(res)%20%7B%5Cn%20%20%20%20%20%20%20%20alert('data%20from%20c.html%20---%3E%20'%20%2B%20res)%3B%5Cn%20%20%20%20%7D%5Cn%3C%2Fscript%3E%22%2C%22heightLimit%22%3Atrue%2C%22margin%22%3Atrue%2C%22id%22%3A%22VnWVX%22%7D"></div><div><span class="lake-fontsize-12" style="color: #1C1F21; background-color: #F8FAFC;">2)b.html </span></div><div data-card-type="block" data-ready-card="codeblock" data-card-value="data:%7B%22mode%22%3A%22plain%22%2C%22code%22%3A%22%3Ciframe%20id%3D%5C%22iframe%5C%22%20src%3D%5C%22http%3A%2F%2Fwww.domain1.com%2Fc.html%5C%22%20style%3D%5C%22display%3Anone%3B%5C%22%3E%3C%2Fiframe%3E%5Cn%3Cscript%3E%5Cn%20%20%20%20var%20iframe%20%3D%20document.getElementById('iframe')%3B%5Cn%20%5Cn%20%20%20%20%2F%2F%20%E7%9B%91%E5%90%ACa.html%E4%BC%A0%E6%9D%A5%E7%9A%84hash%E5%80%BC%EF%BC%8C%E5%86%8D%E4%BC%A0%E7%BB%99c.html%5Cn%20%20%20%20window.onhashchange%20%3D%20function%20()%20%7B%5Cn%20%20%20%20%20%20%20%20iframe.src%20%3D%20iframe.src%20%2B%20location.hash%3B%5Cn%20%20%20%20%7D%3B%5Cn%3C%2Fscript%3E%22%2C%22heightLimit%22%3Atrue%2C%22margin%22%3Atrue%2C%22id%22%3A%22ufkco%22%7D"></div><div><span class="lake-fontsize-12" style="color: #1C1F21; background-color: #F8FAFC;">3)c.html </span></div><div data-card-type="block" data-ready-card="codeblock" data-card-value="data:%7B%22mode%22%3A%22plain%22%2C%22code%22%3A%22%3Cscript%3E%5Cn%20%20%20%20%2F%2F%20%E7%9B%91%E5%90%ACb.html%E4%BC%A0%E6%9D%A5%E7%9A%84hash%E5%80%BC%5Cn%20%20%20%20window.onhashchange%20%3D%20function%20()%20%7B%5Cn%20%20%20%20%20%20%20%20%2F%2F%20%E5%86%8D%E9%80%9A%E8%BF%87%E6%93%8D%E4%BD%9C%E5%90%8C%E5%9F%9Fa.html%E7%9A%84js%E5%9B%9E%E8%B0%83%EF%BC%8C%E5%B0%86%E7%BB%93%E6%9E%9C%E4%BC%A0%E5%9B%9E%5Cn%20%20%20%20%20%20%20%20window.parent.parent.onCallback('hello%3A%20'%20%2B%20location.hash.replace('%23user%3D'%2C%20''))%3B%5Cn%20%20%20%20%7D%3B%5Cn%3C%2Fscript%3E%22%2C%22heightLimit%22%3Atrue%2C%22margin%22%3Atrue%2C%22id%22%3A%22VNFyx%22%7D"></div><h3 id="HACYi"><span style="color: #1C1F21;"><span style="background-color: #F8FAFC;">7、window.name + iframe跨域</span></span></h3><div><span style="color: #1C1F21;"><span style="background-color: #F8FAFC;">  window.name属性的独特之处:name值在不同的页面(甚至不同域名)加载后依旧存在,并且可以支持非常长的 name 值(2MB)。<br /><br />1)a.html </span></span></div><div data-card-type="block" data-ready-card="codeblock" data-card-value="data:%7B%22mode%22%3A%22plain%22%2C%22code%22%3A%22var%20proxy%20%3D%20function(url%2C%20callback)%20%7B%5Cn%20%20%20%20var%20state%20%3D%200%3B%5Cn%20%20%20%20var%20iframe%20%3D%20document.createElement('iframe')%3B%5Cn%20%5Cn%20%20%20%20%2F%2F%20%E5%8A%A0%E8%BD%BD%E8%B7%A8%E5%9F%9F%E9%A1%B5%E9%9D%A2%5Cn%20%20%20%20iframe.src%20%3D%20url%3B%5Cn%20%5Cn%20%20%20%20%2F%2F%20onload%E4%BA%8B%E4%BB%B6%E4%BC%9A%E8%A7%A6%E5%8F%912%E6%AC%A1%EF%BC%8C%E7%AC%AC1%E6%AC%A1%E5%8A%A0%E8%BD%BD%E8%B7%A8%E5%9F%9F%E9%A1%B5%EF%BC%8C%E5%B9%B6%E7%95%99%E5%AD%98%E6%95%B0%E6%8D%AE%E4%BA%8Ewindow.name%5Cn%20%20%20%20iframe.onload%20%3D%20function()%20%7B%5Cn%20%20%20%20%20%20%20%20if%20(state%20%3D%3D%3D%201)%20%7B%5Cn%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20%E7%AC%AC2%E6%AC%A1onload(%E5%90%8C%E5%9F%9Fproxy%E9%A1%B5)%E6%88%90%E5%8A%9F%E5%90%8E%EF%BC%8C%E8%AF%BB%E5%8F%96%E5%90%8C%E5%9F%9Fwindow.name%E4%B8%AD%E6%95%B0%E6%8D%AE%5Cn%20%20%20%20%20%20%20%20%20%20%20%20callback(iframe.contentWindow.name)%3B%5Cn%20%20%20%20%20%20%20%20%20%20%20%20destoryFrame()%3B%5Cn%20%5Cn%20%20%20%20%20%20%20%20%7D%20else%20if%20(state%20%3D%3D%3D%200)%20%7B%5Cn%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20%E7%AC%AC1%E6%AC%A1onload(%E8%B7%A8%E5%9F%9F%E9%A1%B5)%E6%88%90%E5%8A%9F%E5%90%8E%EF%BC%8C%E5%88%87%E6%8D%A2%E5%88%B0%E5%90%8C%E5%9F%9F%E4%BB%A3%E7%90%86%E9%A1%B5%E9%9D%A2%5Cn%20%20%20%20%20%20%20%20%20%20%20%20iframe.contentWindow.location%20%3D%20'http%3A%2F%2Fwww.domain1.com%2Fproxy.html'%3B%5Cn%20%20%20%20%20%20%20%20%20%20%20%20state%20%3D%201%3B%5Cn%20%20%20%20%20%20%20%20%7D%5Cn%20%20%20%20%7D%3B%5Cn%20%5Cn%20%20%20%20document.body.appendChild(iframe)%3B%5Cn%20%5Cn%20%20%20%20%2F%2F%20%E8%8E%B7%E5%8F%96%E6%95%B0%E6%8D%AE%E4%BB%A5%E5%90%8E%E9%94%80%E6%AF%81%E8%BF%99%E4%B8%AAiframe%EF%BC%8C%E9%87%8A%E6%94%BE%E5%86%85%E5%AD%98%EF%BC%9B%E8%BF%99%E4%B9%9F%E4%BF%9D%E8%AF%81%E4%BA%86%E5%AE%89%E5%85%A8%EF%BC%88%E4%B8%8D%E8%A2%AB%E5%85%B6%E4%BB%96%E5%9F%9Fframe%20js%E8%AE%BF%E9%97%AE%EF%BC%89%5Cn%20%20%20%20function%20destoryFrame()%20%7B%5Cn%20%20%20%20%20%20%20%20iframe.contentWindow.document.write('')%3B%5Cn%20%20%20%20%20%20%20%20iframe.contentWindow.close()%3B%5Cn%20%20%20%20%20%20%20%20document.body.removeChild(iframe)%3B%5Cn%20%20%20%20%7D%5Cn%7D%3B%5Cn%20%5Cn%2F%2F%20%E8%AF%B7%E6%B1%82%E8%B7%A8%E5%9F%9Fb%E9%A1%B5%E9%9D%A2%E6%95%B0%E6%8D%AE%5Cnproxy('http%3A%2F%2Fwww.domain2.com%2Fb.html'%2C%20function(data)%7B%5Cn%20%20%20%20alert(data)%3B%5Cn%7D)%3B%22%2C%22heightLimit%22%3Atrue%2C%22margin%22%3Atrue%2C%22id%22%3A%22wIvIC%22%7D"></div><div><span style="color: #1C1F21;"><span style="background-color: #F8FAFC;">2)proxy.html <br />  中间代理页,与a.html同域,内容为空即可。</span></span></div><div><span style="color: #1C1F21;"><span style="background-color: #F8FAFC;">3)b.html </span></span></div><div data-card-type="block" data-ready-card="codeblock" data-card-value="data:%7B%22mode%22%3A%22plain%22%2C%22code%22%3A%22%3Cscript%3E%5Cn%20%20%20%20window.name%20%3D%20'This%20is%20domain2%20data!'%3B%5Cn%3C%2Fscript%3E%22%2C%22heightLimit%22%3Atrue%2C%22margin%22%3Atrue%2C%22id%22%3A%22uDqZv%22%7D"></div><div><span style="color: #1C1F21;"><span style="background-color: #F8FAFC;">通过iframe的src属性由外域转向本地域,跨域数据即由iframe的window.name从外域传递到本地域。这个就巧妙地绕过了浏览器的跨域访问限制,但同时它又是安全操作。</span></span></div><h3 id="QFpJc"><a name="t14"></a><span style="color: #1C1F21;"><span style="background-color: #F8FAFC;">8、postMessage跨域</span></span></h3><div><span style="color: #1C1F21;"><span style="background-color: #F8FAFC;">postMessage是HTML5 XMLHttpRequest Level 2中的API,且是为数不多可以跨域操作的window属性之一,它可用于解决以下方面的问题:</span></span></div><ul><li><span style="color: #1C1F21;"><span style="background-color: #F8FAFC;">页面和其打开的新窗口的数据传递</span></span></li></ul><ul><li><span style="color: #1C1F21;"><span style="background-color: #F8FAFC;">多窗口之间消息传递</span></span></li><li><span style="color: #1C1F21;"><span style="background-color: #F8FAFC;">页面与嵌套的iframe消息传递</span></span></li><li><span style="color: #1C1F21;"><span style="background-color: #F8FAFC;">上面三个场景的跨域数据传递</span></span></li></ul><div><span style="color: #1C1F21;"><span style="background-color: #F8FAFC;">用法:postMessage(data,origin)方法接受两个参数:</span></span></div><ul><li><span style="color: #1C1F21;"><span style="background-color: #F8FAFC;"><strong>data</strong>: html5规范支持任意基本类型或可复制的对象,但部分浏览器只支持字符串,所以传参时最好用JSON.stringify()序列化。</span></span></li></ul><ul><li><span style="color: #1C1F21;"><span style="background-color: #F8FAFC;"><strong>origin</strong>: 协议+主机+端口号,也可以设置为"*",表示可以传递给任意窗口,如果要指定和当前窗口同源的话设置为"/"。</span></span></li></ul><div><span style="color: #1C1F21;"><span style="background-color: #F8FAFC;">1)a.html</span></span></div><div data-card-type="block" data-ready-card="codeblock" data-card-value="data:%7B%22mode%22%3A%22plain%22%2C%22code%22%3A%22%3Ciframe%20id%3D%5C%22iframe%5C%22%20src%3D%5C%22http%3A%2F%2Fwww.domain2.com%2Fb.html%5C%22%20style%3D%5C%22display%3Anone%3B%5C%22%3E%3C%2Fiframe%3E%5Cn%3Cscript%3E%20%20%20%20%20%20%20%5Cn%20%20%20%20var%20iframe%20%3D%20document.getElementById('iframe')%3B%5Cn%20%20%20%20iframe.onload%20%3D%20function()%20%7B%5Cn%20%20%20%20%20%20%20%20var%20data%20%3D%20%7B%5Cn%20%20%20%20%20%20%20%20%20%20%20%20name%3A%20'aym'%5Cn%20%20%20%20%20%20%20%20%7D%3B%5Cn%20%20%20%20%20%20%20%20%2F%2F%20%E5%90%91domain2%E4%BC%A0%E9%80%81%E8%B7%A8%E5%9F%9F%E6%95%B0%E6%8D%AE%5Cn%20%20%20%20%20%20%20%20iframe.contentWindow.postMessage(JSON.stringify(data)%2C%20'http%3A%2F%2Fwww.domain2.com')%3B%5Cn%20%20%20%20%7D%3B%5Cn%20%5Cn%20%20%20%20%2F%2F%20%E6%8E%A5%E5%8F%97domain2%E8%BF%94%E5%9B%9E%E6%95%B0%E6%8D%AE%5Cn%20%20%20%20window.addEventListener('message'%2C%20function(e)%20%7B%5Cn%20%20%20%20%20%20%20%20alert('data%20from%20domain2%20---%3E%20'%20%2B%20e.data)%3B%5Cn%20%20%20%20%7D%2C%20false)%3B%5Cn%3C%2Fscript%3E%22%2C%22heightLimit%22%3Atrue%2C%22margin%22%3Atrue%2C%22id%22%3A%22wuIeL%22%7D"></div><div><span class="lake-fontsize-12" style="color: #1C1F21; background-color: #F8FAFC;">2)b.html</span></div><div data-card-type="block" data-ready-card="codeblock" data-card-value="data:%7B%22mode%22%3A%22plain%22%2C%22code%22%3A%22%3Cscript%3E%5Cn%20%20%20%20%2F%2F%20%E6%8E%A5%E6%94%B6domain1%E7%9A%84%E6%95%B0%E6%8D%AE%5Cn%20%20%20%20window.addEventListener('message'%2C%20function(e)%20%7B%5Cn%20%20%20%20%20%20%20%20alert('data%20from%20domain1%20---%3E%20'%20%2B%20e.data)%3B%5Cn%20%5Cn%20%20%20%20%20%20%20%20var%20data%20%3D%20JSON.parse(e.data)%3B%5Cn%20%20%20%20%20%20%20%20if%20(data)%20%7B%5Cn%20%20%20%20%20%20%20%20%20%20%20%20data.number%20%3D%2016%3B%5Cn%20%5Cn%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20%E5%A4%84%E7%90%86%E5%90%8E%E5%86%8D%E5%8F%91%E5%9B%9Edomain1%5Cn%20%20%20%20%20%20%20%20%20%20%20%20window.parent.postMessage(JSON.stringify(data)%2C%20'http%3A%2F%2Fwww.domain1.com')%3B%5Cn%20%20%20%20%20%20%20%20%7D%5Cn%20%20%20%20%7D%2C%20false)%3B%5Cn%3C%2Fscript%3E%22%2C%22heightLimit%22%3Atrue%2C%22margin%22%3Atrue%2C%22id%22%3A%22TQZjn%22%7D"></div><h3 id="dZwSL"><span style="color: #1C1F21;"><span style="background-color: #F8FAFC;">9、WebSocket协议跨域</span></span></h3><div><span style="color: #1C1F21;"><span style="background-color: #F8FAFC;">  WebSocket protocol是HTML5一种新的协议。它实现了浏览器与服务器全双工通信,同时允许跨域通讯,是server push技术的一种很好的实现。</span></span></div><div><span class="lake-fontsize-12" style="color: #1C1F21; background-color: #F8FAFC;">原生WebSocket API使用起来不太方便,使用Socket.io,它很好地封装了webSocket接口,提供了更简单、灵活的接口,也对不支持webSocket的浏览器提供了向下兼容。</span></div><div><br /></div><div><span class="lake-fontsize-12" style="color: #1C1F21; background-color: #F8FAFC;">1)前端代码:</span></div><div data-card-type="block" data-ready-card="codeblock" data-card-value="data:%7B%22mode%22%3A%22plain%22%2C%22code%22%3A%22%3Cdiv%3Euser%20input%EF%BC%9A%3Cinput%20type%3D%5C%22text%5C%22%3E%3C%2Fdiv%3E%5Cn%3Cscript%20src%3D%5C%22https%3A%2F%2Fcdn.bootcss.com%2Fsocket.io%2F2.2.0%2Fsocket.io.js%5C%22%3E%3C%2Fscript%3E%5Cn%3Cscript%3E%5Cnvar%20socket%20%3D%20io('http%3A%2F%2Fwww.domain2.com%3A8080')%3B%5Cn%20%5Cn%2F%2F%20%E8%BF%9E%E6%8E%A5%E6%88%90%E5%8A%9F%E5%A4%84%E7%90%86%5Cnsocket.on('connect'%2C%20function()%20%7B%5Cn%20%20%20%20%2F%2F%20%E7%9B%91%E5%90%AC%E6%9C%8D%E5%8A%A1%E7%AB%AF%E6%B6%88%E6%81%AF%5Cn%20%20%20%20socket.on('message'%2C%20function(msg)%20%7B%5Cn%20%20%20%20%20%20%20%20console.log('data%20from%20server%3A%20---%3E%20'%20%2B%20msg)%3B%20%5Cn%20%20%20%20%7D)%3B%5Cn%20%5Cn%20%20%20%20%2F%2F%20%E7%9B%91%E5%90%AC%E6%9C%8D%E5%8A%A1%E7%AB%AF%E5%85%B3%E9%97%AD%5Cn%20%20%20%20socket.on('disconnect'%2C%20function()%20%7B%20%5Cn%20%20%20%20%20%20%20%20console.log('Server%20socket%20has%20closed.')%3B%20%5Cn%20%20%20%20%7D)%3B%5Cn%7D)%3B%5Cn%20%5Cndocument.getElementsByTagName('input')%5B0%5D.onblur%20%3D%20function()%20%7B%5Cn%20%20%20%20socket.send(this.value)%3B%5Cn%7D%3B%5Cn%3C%2Fscript%3E%22%2C%22heightLimit%22%3Atrue%2C%22margin%22%3Atrue%2C%22id%22%3A%22t7D8Q%22%7D"></div><div><span class="lake-fontsize-12" style="color: #1C1F21; background-color: #F8FAFC;">2)Nodejs socket后台:</span></div><div data-card-type="block" data-ready-card="codeblock" data-card-value="data:%7B%22mode%22%3A%22plain%22%2C%22code%22%3A%22var%20http%20%3D%20require('http')%3B%5Cnvar%20socket%20%3D%20require('socket.io')%3B%5Cn%20%5Cn%2F%2F%20%E5%90%AFhttp%E6%9C%8D%E5%8A%A1%5Cnvar%20server%20%3D%20http.createServer(function(req%2C%20res)%20%7B%5Cn%20%20%20%20res.writeHead(200%2C%20%7B%5Cn%20%20%20%20%20%20%20%20'Content-type'%3A%20'text%2Fhtml'%5Cn%20%20%20%20%7D)%3B%5Cn%20%20%20%20res.end()%3B%5Cn%7D)%3B%5Cn%20%5Cnserver.listen('8080')%3B%5Cnconsole.log('Server%20is%20running%20at%20port%208080...')%3B%5Cn%20%5Cn%2F%2F%20%E7%9B%91%E5%90%ACsocket%E8%BF%9E%E6%8E%A5%5Cnsocket.listen(server).on('connection'%2C%20function(client)%20%7B%5Cn%20%20%20%20%2F%2F%20%E6%8E%A5%E6%94%B6%E4%BF%A1%E6%81%AF%5Cn%20%20%20%20client.on('message'%2C%20function(msg)%20%7B%5Cn%20%20%20%20%20%20%20%20client.send('hello%EF%BC%9A'%20%2B%20msg)%3B%5Cn%20%20%20%20%20%20%20%20console.log('data%20from%20client%3A%20---%3E%20'%20%2B%20msg)%3B%5Cn%20%20%20%20%7D)%3B%5Cn%20%5Cn%20%20%20%20%2F%2F%20%E6%96%AD%E5%BC%80%E5%A4%84%E7%90%86%5Cn%20%20%20%20client.on('disconnect'%2C%20function()%20%7B%5Cn%20%20%20%20%20%20%20%20console.log('Client%20socket%20has%20closed.')%3B%20%5Cn%20%20%20%20%7D)%3B%5Cn%7D)%3B%22%2C%22heightLimit%22%3Atrue%2C%22margin%22%3Atrue%2C%22id%22%3A%22MQEzy%22%7D"></div><div><span style="color: #1C1F21;"><span style="background-color: #F8FAFC;"><br /></span></span></div></code></span></span></div>

相关实践学习
基于函数计算快速搭建Hexo博客系统
本场景介绍如何使用阿里云函数计算服务命令行工具快速搭建一个Hexo博客。
相关文章
|
2月前
|
前端开发
前端跳转链接报错403的原因以及解决方案
前端跳转链接报错403的原因以及解决方案
144 1
|
2月前
|
JSON 前端开发 安全
前端开发中的跨域问题及解决方案
在前端开发中,跨域是一个常见但又令人头疼的问题。本文将深入探讨跨域产生的原因以及一些常见的解决方案,帮助开发者更好地理解和处理跨域情况。
|
18天前
|
Web App开发 移动开发 运维
跨域解决方案[前端+后端]
跨域解决方案[前端+后端]
25 0
|
28天前
|
前端开发
无法解锁/var/lib/dpkg/lock-frontend和无法获取 dpkg 前端锁 (/var/lib/dpkg/lock-frontend)【解决方案】
无法解锁/var/lib/dpkg/lock-frontend和无法获取 dpkg 前端锁 (/var/lib/dpkg/lock-frontend)【解决方案】
|
2月前
|
前端开发 JavaScript NoSQL
从前端到后端:构建全栈应用的技术挑战与解决方案
在当今互联网时代,全栈开发成为越来越受欢迎的技术趋势。本文将深入探讨从前端到后端的全栈开发过程中所面临的技术挑战,并提出相应的解决方案,涵盖前端框架选择、后端技术架构、数据库设计以及跨平台兼容性等关键问题。
|
2月前
|
前端开发
前端性能优化:掌握解决方案
我们常说性能永远是第一需求,作为一个前端工程师,不管使用什么框架,不管从事什么类型的网站或应用开发,只要是项目被用户使用,性能优化就永远是你需要关注的问题。通常情况下,工程师们在深入了解前端技术的原理后,才能总结出性能优化的方案,需要多年经验的积累。前端技术日新月异,优秀的性能优化方案在近几年也层出不穷。本课程带你使用当今行业中非常前沿&专业的方案,解决前端性能优化问题。无论是为了解决工作中的实际问题,还是为了提升能力,这门课都能帮到你。
15 2
前端性能优化:掌握解决方案
|
2月前
|
前端开发 安全 开发者
前端开发中的跨域资源共享(CORS)问题及解决方案探讨
在前端开发中,跨域资源共享(CORS)是一个常见且重要的问题。本文将深入探讨CORS的原理、影响以及解决方案,帮助开发者更好地应对跨域请求问题。
|
2月前
|
前端开发 JavaScript 容器
前端vw自适应解决方案,适用pc端以及移动端,适用webpack以及vite,适用vue以及react
前端vw自适应解决方案,适用pc端以及移动端,适用webpack以及vite,适用vue以及react
74 0
|
2月前
|
前端开发
前端播放第三方外链视频报403 forbidden的原因及解决方案
前端播放第三方外链视频报403 forbidden的原因及解决方案
67 0
|
2月前
|
JSON 前端开发 安全
前端解决跨域的六种方法
跨域问题是指当一个网页试图访问来自不同源(域名、协议、端口)的资源时,浏览器会出于安全考虑而限制这种访问。这是因为浏览器的同源策略防止了恶意网站获取其他网站的敏感信息。