跨域是什么意思(跨域是什么原因导致的)

跨域是什么意思(跨域是什么原因导致的)p style padding top 8px padding bottom 8px line height 26px 嗯 又来了 又说到跨域了 这是一个老生常谈的话题 以前我觉得这种基础文章没有什么好写的 会想着你去了解底层啊 不是很简单吗 但是最近在开发一个 strong vscode 插件 strong 发现 p

大家好,我是讯享网,很高兴认识大家。



 <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">嗯。又来了,又说到跨域了,这是一个老生常谈的话题,以前我觉得这种基础文章没有什么好写的,会想着你去了解底层啊,不是很简单吗。但是最近在开发一个 <strong>「vscode 插件」</strong> 发现,当你刚入门一样东西的时候,你不会想这么多,因为你对他不熟悉,当你遇到不会的东西,你就是想先找到解决方案,然后通过这个解决方案再去深入理解。就比如跨域,新人或者刚接触的人对它并不是那么熟悉,所以说列出一些自己积累的方案,以及一些常用的场景来给他人带来一些解决问题的思路,这件事是有意义的。(写完之后还发现真香。以后忘了还能回来看看)</p> <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">其实现在的环境对于刚入门的前端来说,非常的不友好,一方面吧,很多刚新人没有经历过工具的变更时代,另一方面框架的迭代更新速度很快。在以前你可能掌握几种常见的手法就好了。但是现在 、、,这些脚手架都进行了一层封装,对于熟悉的人可能很简单,但是对于还未入门的人来说,简直就是一个黑盒,虽然用起来很方便,但是某一天遇到了问题,你对它不熟悉,你就会不知道所错。(但是别慌,主流 cli 的跨域方式我都会讲到)</p> <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">讲着讲着有点偏离方向,可能我讲的也并不一定是正确的。下面切入正题。</p> <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">本文会以 <strong>「「What-How-Why」」</strong> 的方式来进行讲解。而在在 How (如何解决跨域,将会提供标题的 11 种方案。)</p> <p style="padding-top:8px;padding-bottom:8px;line-height:26px;"><strong>「重要的说明: 在文中,web 端地址为 localhost:8000 服务端地址为 localhost:8080,这一点希望你能记住,会贯穿全文,你也可以把此处的两端的地址代入你自己的地址。」</strong></p> <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">cors</p> <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">以下所有代码均在 https://github.com/hua/node-demo/tree/master/node-cors</p> <p style="padding-top:8px;padding-bottom:8px;line-height:26px;"></p> <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">跨域问题其实就是浏览器的同源策略所导致的。</p> <blockquote style="border-top:none;border-right:none;border-bottom:none;font-size:0.9em;overflow:auto;background:rgba(0, 0, 0, 0.05);color:rgb(106, 115, 125);padding:10px 10px 10px 20px;margin-bottom:20px;margin-top:20px;border-left-color:rgb(255, 218, 169);"> <p style="padding-top:8px;padding-bottom:8px;color:black;line-height:26px;font-size:15px;">❝</p> <p style="padding-top:8px;padding-bottom:8px;color:black;line-height:26px;font-size:15px;">「同源策略」是一个重要的安全策略,它用于限制一个origin的文档或者它加载的脚本如何能与另一个源的资源进行交互。它能帮助阻隔恶意文档,减少可能被攻击的媒介。</p> <p style="padding-top:8px;padding-bottom:8px;color:black;line-height:26px;font-size:15px;">--来源 MDN</p> <p style="padding-top:8px;padding-bottom:8px;color:black;line-height:26px;font-size:15px;">❞</p> </blockquote> <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">当跨域时会收到以下错误</p> <p style="padding-top:8px;padding-bottom:8px;line-height:26px;"><img style="display:block;margin-right:auto;margin-left:auto;width:323px !important;height:11.0657px !important;" src="https://r.sinaimg.cn/large/article/d78c1d04553c1a2255e24c8c170e2689" alt=""><br></p> <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">那么如何才算是同源呢?先来看看 url 的组成部分</p> <pre style="margin-top:10px;margin-bottom:10px;border-radius:5px;box-shadow:rgba(0, 0, 0, 0.55) 0px 2px 10px;"></pre> <p style="padding-top:8px;padding-bottom:8px;line-height:26px;"><br></p> <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">只有当</p> <p style="padding-top:8px;padding-bottom:8px;line-height:26px;"><strong>「protocol(协议)、domain(域名)、port(端口)三者一致。」</strong></p> <p style="padding-top:8px;padding-bottom:8px;line-height:26px;"><strong>「protocol(协议)、domain(域名)、port(端口)三者一致。」</strong></p> <p style="padding-top:8px;padding-bottom:8px;line-height:26px;"><strong>「protocol(协议)、domain(域名)、port(端口)三者一致。」</strong></p> <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">才是同源。</p> <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">以下协议、域名、端口一致。</p> <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">http://www.example.com:80/a.js</p> <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">http://www.example.com:80/b.js</p> <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">以下这种看上去再相似也没有用,都不是同源。</p> <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">http://www.example.com:8080</p> <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">http://www2.example.com:80</p> <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">在这里注意一下啊,这里是为了突出端口的区别才写上端口。在默认情况下 http 可以省略端口 80, https 省略 443。这别到时候闹笑话了,你和我说 http://www.example.com:80 和 http://www.example.com 不是同源,他俩是一个东西。</p> <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">http://www.example.com:80 === http://www.example.com</p> <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">https://www.example.com:443 === https://www.example.com</p> <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">唔,还是要说明一下。</p> <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">跨域资源共享(CORS) 是一种机制,它使用额外的 HTTP 头来告诉浏览器 让运行在一个 origin (domain) 上的 Web 应用被准许访问来自不同源服务器上的指定的资源。当一个资源从与该资源本身所在的服务器「不同的域、协议或端口」<strong>请求一个资源时,资源会发起一个</strong>「跨域 HTTP 请求」。</p> <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">而在 cors 中会有 和 的概念。</p> <p style="padding-top:8px;padding-bottom:8px;line-height:26px;"><strong>「浏览器支持情况」</strong></p> <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">当你使用 IE&lt;=9, Opera&lt;12, or Firefox&lt;3.5 或者更加老的浏览器,这个时候请使用 JSONP 。</p> <h4 style="margin-top:30px;margin-bottom:15px;font-weight:bold;font-size:18px;"><span style="font-size:16px;">a.简单请求</span></h4> <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">不会触发 CORS 预检请求。这样的请求为“简单请求”,请注意,该术语并不属于 Fetch (其中定义了 CORS)规范。若请求满足所有下述条件,则该请求可视为“简单请求”:</p> <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">情况一: 使用以下方法(意思就是以下请求意外的都是非简单请求)</p> 

讯享网

情况二: 人为设置以下集合外的请求头

情况三:的值仅限于下列三者之一:(例如 application/json 为非简单请求)

情况四:

请求中的任意 对象均没有注册任何事件监听器; 对象可以使用 属性访问。

情况五:

请求中没有使用 对象。

b.非简单请求

除以上情况外的。

c.Node 中的解决方案

原生方式

我们来看下后端部分的解决方案。 中 的解决代码.

讯享网
第三方中间件

为了方便也可以直接使用中间件

 
关于 cors 的 cookie 问题

想要传递 需要满足 3 个条件

1.web 请求设置

这里默认情况下在跨域请求,浏览器是不带 cookie 的。但是我们可以通过设置 来进行传递 .


讯享网

讯享网

2. 为

3.为非

这里请求的方式,在 中是能看到返回值的,但是只要不满足以上其一,浏览器会报错,获取不到返回值。

 


讯享网


d.前端示例

分别演示一下前端部分 和

简单请求
 
非简单请求

这里我们加入了一个非集合内的 头 来达到非简单请求的目的。

讯享网
小结

1、 在新版的 chrome 中,如果你发送了复杂请求,你却看不到 请求。可以在这里设置 设置成 ,重启浏览器。对于非简单请求就能看到 请求了。

2、 一般情况下后端接口是不会开启这个跨域头的,除非是一些与用户无关的不太重要的接口。

     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">代理的思路为,利用服务端请求不会跨域的特性,让接口和当前站点同域。</p>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;"><strong>「代理前」</strong></p>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;"><br></p>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;"><strong>「代理后」</strong></p>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;"><br></p>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">这样,所有的资源以及请求都在一个域名下了。</p>
     <h4 style="margin-top:30px;margin-bottom:15px;font-weight:bold;font-size:18px;"><span style="font-size:16px;">a.cli 工具中的代理</span></h4>
     <h5 style="margin-top:30px;margin-bottom:15px;font-weight:bold;">1) Webpack (4.x)</h5>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">在中可以配置来快速获得接口代理的能力。</p>
     <pre style="margin-top:10px;margin-bottom:10px;border-radius:5px;box-shadow:rgba(0, 0, 0, 0.55) 0px 2px 10px;"></pre>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">修改前端接口请求方式,改为不带域名。(因为现在是同域请求了)</p>
     <pre style="margin-top:10px;margin-bottom:10px;border-radius:5px;box-shadow:rgba(0, 0, 0, 0.55) 0px 2px 10px;"></pre>
     <h5 style="margin-top:30px;margin-bottom:15px;font-weight:bold;">2) Vue-cli 2.x</h5>
     <pre style="margin-top:10px;margin-bottom:10px;border-radius:5px;box-shadow:rgba(0, 0, 0, 0.55) 0px 2px 10px;"></pre>
     <h5 style="margin-top:30px;margin-bottom:15px;font-weight:bold;">3) Vue-cli 3.x</h5>
     <pre style="margin-top:10px;margin-bottom:10px;border-radius:5px;box-shadow:rgba(0, 0, 0, 0.55) 0px 2px 10px;"></pre>
     <h5 style="margin-top:30px;margin-bottom:15px;font-weight:bold;">4) Parcel (2.x)</h5>
     <pre style="margin-top:10px;margin-bottom:10px;border-radius:5px;box-shadow:rgba(0, 0, 0, 0.55) 0px 2px 10px;"></pre>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">看到这里,心里一句 xxx 就会脱口而出,一会写配置文件,一会 proxyTable ,一会 proxy,怎么这么多的形式?学不动了学不动了。。。不过也不用慌,还是有方法的。以上所有配置都是有着共同的底层包 http-proxy-middleware .里面需要用到的各种  , 等功能,直接看这个库的配置就可以了。关于 http-proxy-middleware 这个库的原理可以看我这篇文章 https://github.com/hua1995116/proxy 当然了。。。对于配置的位置入口还是非统一的。教一个搜索的技巧吧,上面配置写哪里都不用记的,想要哪个框架的 直接 google 搜索 xxx proxy 就行了。</p>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">例如 vue-cli 2 proxy 、 webpack proxy 等等....基本会搜到有官网的配置答案,通用且 nice。</p>
     <h4 style="margin-top:30px;margin-bottom:15px;font-weight:bold;font-size:18px;"><span style="font-size:16px;">b.使用自己的代理工具</span></h4>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">cors-anywhere</p>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;"><strong>「服务端」</strong></p>
     <pre style="margin-top:10px;margin-bottom:10px;border-radius:5px;box-shadow:rgba(0, 0, 0, 0.55) 0px 2px 10px;"></pre>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;"><strong>「前端代码」</strong></p>
     <pre style="margin-top:10px;margin-bottom:10px;border-radius:5px;box-shadow:rgba(0, 0, 0, 0.55) 0px 2px 10px;"></pre>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;"><strong>「效果展示」</strong></p>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;"><br></p>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;"><strong>「缺点」</strong></p>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">无法专递 cookie,原因是因为这个是一个代理库,作者觉得中间传递 cookie 太不安全了。https://github.com/Rob--W/cors-anywhere/issues/208#issuecomment-575254153</p>
     <h4 style="margin-top:30px;margin-bottom:15px;font-weight:bold;font-size:18px;"><span style="font-size:16px;">c.charles</span></h4>
     <h5 style="margin-top:30px;margin-bottom:15px;font-weight:bold;">介绍</h5>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">这是一个测试、开发的神器。介绍与使用</p>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">利用 charles 进行跨域,本质就是请求的拦截与代理。</p>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">在  中设置代理</p>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;"><img style="display:block;margin-right:auto;margin-left:auto;width:323px !important;height:18.4167px !important;" src="https://r.sinaimg.cn/large/article/6f061f5ec71b0d3f447c69a23c6c1e93" alt=""><br></p>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;"><br></p>
     <h5 style="margin-top:30px;margin-bottom:15px;font-weight:bold;">前端代码</h5>
     <pre style="margin-top:10px;margin-bottom:10px;border-radius:5px;box-shadow:rgba(0, 0, 0, 0.55) 0px 2px 10px;"></pre>
     <h5 style="margin-top:30px;margin-bottom:15px;font-weight:bold;">后端代码</h5>
     <pre style="margin-top:10px;margin-bottom:10px;border-radius:5px;box-shadow:rgba(0, 0, 0, 0.55) 0px 2px 10px;"></pre>
     <h5 style="margin-top:30px;margin-bottom:15px;font-weight:bold;">效果</h5>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">访问 http://localhost:8000/charles</p>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;"><br></p>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;"><br></p>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">完美解决。</p>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">唔。这里又有一个注意点。在  中会出现  抓不到本地包的情况。这个时候需要自定义一个域名,然后配置指定到。然后修改访问方式 。</p>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;"><img style="display:block;margin-right:auto;margin-left:auto;width:323px !important;height:25.7987px !important;" src="https://r.sinaimg.cn/large/article/20bb8731043c60ce970085cb065ee37d" alt=""><br></p>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;"><img style="display:block;margin-right:auto;margin-left:auto;width:323px !important;height:13.8034px !important;" src="https://r.sinaimg.cn/large/article/3ff7de369e11381d100956043d326723" alt=""><br></p>

     <h5 style="margin-top:30px;margin-bottom:15px;font-weight:bold;">介绍</h5>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">Nginx 则是通过反向代理的方式,(这里也需要自定义一个域名)这里就是保证我当前域,能获取到静态资源和接口,不关心是怎么获取的。nginx 安装教程</p>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;"><br></p>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">配置下 hosts</p>
     <pre style="margin-top:10px;margin-bottom:10px;border-radius:5px;box-shadow:rgba(0, 0, 0, 0.55) 0px 2px 10px;"></pre>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">配置 nginx</p>
     <pre style="margin-top:10px;margin-bottom:10px;border-radius:5px;box-shadow:rgba(0, 0, 0, 0.55) 0px 2px 10px;"></pre>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">启动 nginx</p>
     <pre style="margin-top:10px;margin-bottom:10px;border-radius:5px;box-shadow:rgba(0, 0, 0, 0.55) 0px 2px 10px;"></pre>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">重启 nginx</p>
     <pre style="margin-top:10px;margin-bottom:10px;border-radius:5px;box-shadow:rgba(0, 0, 0, 0.55) 0px 2px 10px;"></pre>
     <h5 style="margin-top:30px;margin-bottom:15px;font-weight:bold;">实现</h5>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">前端代码</p>
     <pre style="margin-top:10px;margin-bottom:10px;border-radius:5px;box-shadow:rgba(0, 0, 0, 0.55) 0px 2px 10px;"></pre>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">后端代码</p>
     <pre style="margin-top:10px;margin-bottom:10px;border-radius:5px;box-shadow:rgba(0, 0, 0, 0.55) 0px 2px 10px;"></pre>
     <h5 style="margin-top:30px;margin-bottom:15px;font-weight:bold;">效果</h5>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">访问 </p>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">浏览器显示</p>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;"><br></p>

     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;"> 主要就是利用了  标签没有跨域限制的这个特性来完成的。</p>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;"><strong>「使用限制」</strong></p>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">仅支持 GET 方法,如果想使用完整的 REST 接口,请使用 CORS 或者其他代理方式。</p>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;"><strong>「流程解析」</strong></p>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">1.前端定义解析函数(例如 jsonpCallback=function(){....})</p>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">2.通过 params 形式包装请求参数,并且声明执行函数(例如 cb=jsonpCallback)</p>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">3.后端获取前端声明的执行函数(jsonpCallback),并以带上参数并调用执行函数的方式传递给前端。</p>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;"><strong>「使用示例」</strong></p>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">后端实现</p>
     <pre style="margin-top:10px;margin-bottom:10px;border-radius:5px;box-shadow:rgba(0, 0, 0, 0.55) 0px 2px 10px;"></pre>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">普通 js 示例</p>
     <pre style="margin-top:10px;margin-bottom:10px;border-radius:5px;box-shadow:rgba(0, 0, 0, 0.55) 0px 2px 10px;"></pre>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">JQuery Ajax 示例</p>
     <pre style="margin-top:10px;margin-bottom:10px;border-radius:5px;box-shadow:rgba(0, 0, 0, 0.55) 0px 2px 10px;"></pre>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;"><strong>「原理解析」</strong></p>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">其实这就是 js 的魔法</p>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">我们先来看最简单的 js 调用。嗯,很自然的调用。</p>
     <pre style="margin-top:10px;margin-bottom:10px;border-radius:5px;box-shadow:rgba(0, 0, 0, 0.55) 0px 2px 10px;"></pre>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">我们稍稍改造一下,外链的形式。</p>
     <pre style="margin-top:10px;margin-bottom:10px;border-radius:5px;box-shadow:rgba(0, 0, 0, 0.55) 0px 2px 10px;"></pre>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">我们再改造一下,我们把这个外链的 js 就当做是一个动态的接口,因为本身资源和接口一样,是一个请求,也包含各种参数,也可以动态化返回。</p>
     <pre style="margin-top:10px;margin-bottom:10px;border-radius:5px;box-shadow:rgba(0, 0, 0, 0.55) 0px 2px 10px;"></pre>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">你仔细品,细细品,是不是 jsonp 有的优势就是 script 加载 js 的优势,加载的方式只不过换了一种说法。这也告诉我们一个道理,很多东西并没有那么神奇,是在你所学的知识范围内。就好比,桃树和柳树,如果你把他们当成很大跨度的东西去记忆理解,那么世上这么多树,你真的要累死了,你把他们都当成是树,哦吼?你会突然发现,你对世界上所有的树都有所了解,他们都会长叶子,光合作用....当然也有个例,但是你只需要去记忆这些细微的差别,抓住主干。。。嗯,反正就这么个道理。</p>

     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">WebSocket 规范定义了一种 API,可在网络浏览器和服务器之间建立“套接字”连接。简单地说:客户端和服务器之间存在持久的连接,而且双方都可以随时开始发送数据。详细教程可以看 https://www.html5rocks.com/zh/tutorials/websockets/basics/</p>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">这种方式本质没有使用了 HTTP, 因此也没有跨域的限制,没有什么过多的解释直接上代码吧。</p>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">前端部分</p>
     <pre style="margin-top:10px;margin-bottom:10px;border-radius:5px;box-shadow:rgba(0, 0, 0, 0.55) 0px 2px 10px;"></pre>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">后端部分</p>
     <pre style="margin-top:10px;margin-bottom:10px;border-radius:5px;box-shadow:rgba(0, 0, 0, 0.55) 0px 2px 10px;"></pre>

     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;"><strong>「window.postMessage()」</strong> 方法可以安全地实现跨源通信。通常,对于两个不同页面的脚本,只有当执行它们的页面位于具有相同的协议(通常为 https),端口号(443 为 https 的默认值),以及主机 (两个页面的模数 设置为相同的值) 时,这两个脚本才能相互通信。<strong>「window.postMessage()」</strong> 方法提供了一种受控机制来规避此限制,只要正确的使用,这种方法就很安全。</p>
     <h4 style="margin-top:30px;margin-bottom:15px;font-weight:bold;font-size:18px;"><span style="font-size:16px;">用途</span></h4>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">1.页面和其打开的新窗口的数据传递</p>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">2.多窗口之间消息传递</p>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">3.页面与嵌套的 iframe 消息传递</p>
     <h4 style="margin-top:30px;margin-bottom:15px;font-weight:bold;font-size:18px;"><span style="font-size:16px;">用法</span></h4>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">详细用法看 https://developer.mozilla.org/zh-CN/docs/Web/API/Window/postMessage</p>
     <pre style="margin-top:10px;margin-bottom:10px;border-radius:5px;box-shadow:rgba(0, 0, 0, 0.55) 0px 2px 10px;"></pre>

示例

讯享网     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">index.html</p>
     <pre style="margin-top:10px;margin-bottom:10px;border-radius:5px;box-shadow:rgba(0, 0, 0, 0.55) 0px 2px 10px;"></pre>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">another.html</p>
     <pre style="margin-top:10px;margin-bottom:10px;border-radius:5px;box-shadow:rgba(0, 0, 0, 0.55) 0px 2px 10px;"></pre>

     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">从第 7 种到第 9 种方式,我觉得别人的写的已经很好了,为了完整性,我就拿别人的了。如有雷同....(不对,就是雷同....)不要说不出来。</p>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;"><strong>「该方式只能用于二级域名相同的情况下,比如  和  适用于该方式」</strong>。只需要给页面添加  表示二级域名都相同就可以实现跨域。</p>
     <pre style="margin-top:10px;margin-bottom:10px;border-radius:5px;box-shadow:rgba(0, 0, 0, 0.55) 0px 2px 10px;"></pre>

     <h4 style="margin-top:30px;margin-bottom:15px;font-weight:bold;font-size:18px;"><span style="font-size:16px;">实现原理</span></h4>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">原理就是通过 url 带 hash ,通过一个非跨域的中间页面来传递数据。</p>
     <h4 style="margin-top:30px;margin-bottom:15px;font-weight:bold;font-size:18px;"><span style="font-size:16px;">实现流程</span></h4>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">一开始 a.html 给 c.html 传一个 hash 值,然后 c.html 收到 hash 值后,再把 hash 值传递给 b.html,最后 b.html 将结果放到 a.html 的 hash 值中。同样的,a.html 和 b.htm l 是同域的,都是 ,而 c.html 是</p>
     <pre style="margin-top:10px;margin-bottom:10px;border-radius:5px;box-shadow:rgba(0, 0, 0, 0.55) 0px 2px 10px;"></pre>

     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">window 对象的 name 属性是一个很特别的属性,当该 window 的 location 变化,然后重新加载,它的 name 属性可以依然保持不变。</p>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">其中 a.html 和 b.html 是同域的,都是,而 c.html 是</p>
     <pre style="margin-top:10px;margin-bottom:10px;border-radius:5px;box-shadow:rgba(0, 0, 0, 0.55) 0px 2px 10px;"></pre>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">b.html 为中间代理页,与 a.html 同域,内容为空。</p>
     <pre style="margin-top:10px;margin-bottom:10px;border-radius:5px;box-shadow:rgba(0, 0, 0, 0.55) 0px 2px 10px;"></pre>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">通过 iframe 的 src 属性由外域转向本地域,跨域数据即由 iframe 的 window.name 从外域传递到本地域。这个就巧妙地绕过了浏览器的跨域访问限制,但同时它又是安全操作。</p>

     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">其实讲下其实跨域问题是浏览器策略,源头是他,那么能否能关闭这个功能呢?</p>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">答案是肯定的。</p>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;"><strong>「注意事项: 因为浏览器是众多 web 页面入口。我们是否也可以像客户端那种,就是用一个单独的专门宿主浏览器,来打开调试我们的开发页面。例如这里以 chrome canary 为例,这个是我专门调试页面的浏览器,不会用它来访问其他 web url。因此它也相对于安全一些。当然这个方式,只限于当你真的被跨域折磨地崩溃的时候才建议使用以下。使用后,请以正常的方式将他打开,以免你不小心用这个模式干了其他的事。」</strong></p>
     <h4 style="margin-top:30px;margin-bottom:15px;font-weight:bold;font-size:18px;"><span style="font-size:16px;">Windows</span></h4>
     <pre style="margin-top:10px;margin-bottom:10px;border-radius:5px;box-shadow:rgba(0, 0, 0, 0.55) 0px 2px 10px;"></pre>
     <h4 style="margin-top:30px;margin-bottom:15px;font-weight:bold;font-size:18px;"><span style="font-size:16px;">Mac</span></h4>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;"> 这个目录可以自定义.</p>
     <pre style="margin-top:10px;margin-bottom:10px;border-radius:5px;box-shadow:rgba(0, 0, 0, 0.55) 0px 2px 10px;"></pre>
     <h4 style="margin-top:30px;margin-bottom:15px;font-weight:bold;font-size:18px;"><span style="font-size:16px;">效果展示</span></h4>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;"><br></p>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">嗯,使用起来很香,但是再次提醒,一般情况千万别轻易使用这个方式,这个方式好比七伤拳,使用的好威力无比,使用不好,很容易伤到自己。</p>

     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">在最一开始,我们知道了,跨域只存在于浏览器端。而浏览器为 web 提供访问入口。我们在可以浏览器内打开很多页面。正是这样的开放形态,所以我们需要对他有所限制。就比如林子大了,什么鸟都有,我们需要有一个统一的规范来进行约定才能保障这个安全性。</p>

     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">这里还是用最常用的方式来讲解,例如用户登录 a 网站,同时新开 tab 打开了 b 网站,如果不限制同源, b 可以像 a 网站发起任何请求,会让不法分子有机可趁。</p>

     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">我举个例子吧, 你先登录下 www.baidu.com ,然后访问我这个网址。</p>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">https://zerolty.com/node-demo/index.html</p>
     <figure style="margin-top:10px;margin-bottom:10px;display:flex;flex-direction:column;justify-content:center;align-items:center;"><figcaption style="margin-top:5px;text-align:center;color:#888;font-size:14px;"><br></figcaption></figure><p style="padding-top:8px;padding-bottom:8px;line-height:26px;"><br></p>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">你会发现,这个和真实的百度一模一样,如果再把域名搞的相似一些,是不是很容易被骗,如果可以进行 dom 操作...那么大家的信息在这种钓鱼网站眼里都是一颗颗小白菜,等着被收割。</p>
     <blockquote style="border-top:none;border-right:none;border-bottom:none;font-size:0.9em;overflow:auto;background:rgba(0, 0, 0, 0.05);color:rgb(106, 115, 125);padding:10px 10px 10px 20px;margin-bottom:20px;margin-top:20px;border-left-color:rgb(255, 218, 169);">
      <p style="padding-top:8px;padding-bottom:8px;color:black;line-height:26px;font-size:15px;">❝</p>
      <p style="padding-top:8px;padding-bottom:8px;color:black;line-height:26px;font-size:15px;">可以在 http 返回头 添加 防止被别人添加至 iframe。</p>
      <p style="padding-top:8px;padding-bottom:8px;color:black;line-height:26px;font-size:15px;">❞</p>
     </blockquote>

     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;">以上最常用的就是前 4 种方式,特别是第 2 种非常常见,我里面也提到了多种示例,大家可以慢慢消化一下。希望未来有更加安全的方式来限制 web ,解决跨域的头疼,哈哈哈哈。</p>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;"><strong>「有一个不成熟的想法,可以搞这么一个浏览器,只让访问内网/本地网络,专门给开发者用来调试页面用,对于静态资源可以配置白名单,这样是不是就没有跨域问题了,23333。上述如有错误,请第一时间指出,我会进行修改,以免给大家来误导。」</strong></p>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;"><span style="color:rgb(171, 25, 66);font-size:20px;font-weight:bold;letter-spacing:0px;"><br></span></p>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;"><span style="color:rgb(171, 25, 66);font-size:20px;font-weight:bold;letter-spacing:0px;">参考</span></p>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;"><em><span style="letter-spacing:0px;font-size:14px;">https://stackoverflow.com/questions/12296910/so-jsonp-or-cors</span></em></p>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;"><em><span style="font-size:14px;">https://juejin.im/post/5c23993de51d457b8c1f4ee1#heading-18</span></em></p>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;"><em><span style="font-size:14px;">https://juejin.im/post/5a6320d56fb9a01cb64ee191</span></em></p>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;"><em><span style="font-size:14px;">https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS</span></em></p>
     <p style="padding-top:8px;padding-bottom:8px;line-height:26px;"><em><span style="font-size:14px;">https://developer.mozilla.org/zh-CN/docs/Web/Security/Same-origin_policy</span></em></p>
小讯
上一篇 2025-06-15 18:24
下一篇 2025-06-03 12:30

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/205923.html