前端跨域原理(前端跨域解决方案)

前端跨域原理(前端跨域解决方案)p id 1I4PN67R 前言 p p id 1I4PN67S 前后端数据交互经常会碰到请求跨域 什么是跨域 以及有哪几种跨域方式 这是本文要探讨的内容 p p id 1I4PN67T 本文完整的源代码请猛戳 github 博客 p

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




讯享网

                <p id="1I4PN67R">前言</p><p id="1I4PN67S">前后端数据交互经常会碰到请求跨域,什么是跨域,以及有哪几种跨域方式,这是本文要探讨的内容。</p><p id="1I4PN67T">本文完整的源代码请猛戳github博客</p><p>一、什么是跨域? 1.什么是同源策略及其限制内容?</p><p class="f_center">同源策略是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,浏览器很容易受到XSS、CSRF等攻击。所谓同源是指"协议+域名+端口"三者相同,即便两个不同的域名指向同一个ip地址,也非同源。<img src="https://nimg.ws.126.net/?url=http%3A%2F%2Fdingyue.ws.126.net%2F2023%2F0209%2Fcb87371aj00rpt7h8000kd200o8005sg00hx0049.jpg&thumbnail=660x2147483647&quality=80&type=jpg"/><br/><strong>同源策略限制内容有:</strong><br/></p><p><ul><li id="1I4PN6E5"></p><p id="1I4PN67V">Cookie、LocalStorage、IndexedDB 等存储性内容</p><p></li><li id="1I4PN6E6"></p><p id="1I4PN680">DOM 节点</p><p></li><li id="1I4PN6E7"></p><p id="1I4PN681">AJAX 请求发送后,结果被浏览器拦截了</p><p></li></ul></p><p id="1I4PN682">但是有三个标签是允许跨域加载资源:</p><p><ul><li id="1I4PN6E8"></p><p></li><li id="1I4PN6E9"></p><p></li><li id="1I4PN6EA"></p><p></li></ul>2.常见跨域场景</p><p id="1I4PN686"><strong>当协议、子域名、主域名、端口号中任意一个不相同时,都算作不同域</strong>。不同域之间相互请求资源,就算作“跨域”。常见跨域场景如下图所示:<img src="https://nimg.ws.126.net/?url=http%3A%2F%2Fdingyue.ws.126.net%2F2023%2F0209%2F609fb4f4j00rpt7h80027d200mz00mrg00hx00hq.jpg&thumbnail=660x2147483647&quality=80&type=jpg"/></p><p id="1I4PN687">特别说明两点:</p><p id="1I4PN688"><strong>第一:如果是协议和端口造成的跨域问题“前台”是无能为力的。</strong></p><p id="1I4PN689"><strong>第二:在跨域问题上,仅仅是通过“URL的首部”来识别而不会根据域名对应的IP地址是否相同来判断。“URL的首部”可以理解为“协议, 域名和端口必须匹配”</strong>。</p><p id="1I4PN68A">这里你或许有个疑问:<strong>请求跨域了,那么请求到底发出去没有?</strong></p><p id="1I4PN68B"><strong>跨域并不是请求发不出去,请求能发出去,服务端能收到请求并正常返回结果,只是结果被浏览器拦截了</strong>。你可能会疑问明明通过表单的方式可以发起跨域请求,为什么 Ajax 就不会?因为归根结底,跨域是为了阻止用户读取到另一个域名下的内容,Ajax 可以获取响应,浏览器认为这不安全,所以拦截了响应。但是表单并不会获取新的内容,所以可以发起跨域请求。同时也说明了跨域并不能完全阻止 CSRF,因为请求毕竟是发出去了。</p><p>二、跨域解决方案 1.jsonp 1) JSONP原理</p><p id="1I4PN68C"><strong>利用</strong></p><p><ol><li><strong></strong></p><p><strong></strong></p><p></li><li><strong></strong></p><p><strong></strong></p><p></li><li><strong></strong></p><p><strong></strong></p><p></li><li><strong></strong></p><p><strong></strong></p><p></li><li><strong></strong></p><p><strong></strong></p><p></li></ol><strong>4.websocket</strong></p><p><strong>Websocket是HTML5的一个持久化的协议,它实现了浏览器与服务器的全双工通信,同时也是跨域的一种解决方案。WebSocket和HTTP都是应用层协议,都基于 TCP 协议。但是<strong>WebSocket 是一种双向通信协议,在建立连接之后,WebSocket 的 server 与 client 都能主动向对方发送或接收数据</strong>。同时,WebSocket 在建立连接时需要借助 HTTP 协议,连接建立好了之后 client 与 server 之间的双向通信就与 HTTP 无关了。</strong></p><p id="1I4PN68J">原生WebSocket API使用起来不太方便,我们使用,它很好地封装了webSocket接口,提供了更简单、灵活的接口,也对不支持webSocket的浏览器提供了向下兼容。</p><p id="1I4PN68K">我们先来看个例子:本地文件socket.html向发生数据和接受数据</p><p><ol><li id="1I4PN6EG"></p><p id="1I4PN68L"></p><p></li><li id="1I4PN6EH"></p><p></li></ol><ol><li id="1I4PN6EI"></p><p id="1I4PN68N"></p><p></li><li id="1I4PN6EJ"></p><p id="1I4PN68O"></p><p></li><li id="1I4PN6EK"></p><p id="1I4PN68P"></p><p></li><li id="1I4PN6EL"></p><p id="1I4PN68Q"></p><p></li><li id="1I4PN6EM"></p><p id="1I4PN68R"></p><p></li><li id="1I4PN6EN"></p><p id="1I4PN68S"></p><p></li><li id="1I4PN6EO"></p><p id="1I4PN68T"></p><p></li><li id="1I4PN6EP"></p><p id="1I4PN68U"></p><p></li><li id="1I4PN6EQ"></p><p id="1I4PN68V"></p><p></li><li id="1I4PN6ER"></p><p id="1I4PN690"></p><p></li><li id="1I4PN6ES"></p><p id="1I4PN691"></p><p></li></ol>5. Node中间件代理(两次跨域)</p><p id="1I4PN692">实现原理:<strong>同源策略是浏览器需要遵循的标准,而如果是服务器向服务器请求就无需遵循同源策略。</strong>代理服务器,需要做以下几个步骤:</p><p><ul><li id="1I4PN6ET"></p><p id="1I4PN693">接受客户端请求 。</p><p></li><li id="1I4PN6EU"></p><p id="1I4PN694">将请求 转发给服务器。</p><p></li><li id="1I4PN6EV"></p><p id="1I4PN695">拿到服务器 响应 数据。</p><p></li><li id="1I4PN6F0"></p><p class="f_center">将 响应 转发给客户端。<img src="https://nimg.ws.126.net/?url=http%3A%2F%2Fdingyue.ws.126.net%2F2023%2F0209%2F3908da7dj00rpt7h9000jd200go006lg00go006l.jpg&thumbnail=660x2147483647&quality=80&type=jpg"/><br/></p><p></li></ul></p><p id="1I4PN697">我们先来看个例子:本地文件index.html文件,通过代理服务器向目标服务器请求数据。</p><p><ol><li id="1I4PN6F1"></p><p id="1I4PN698"></p><p></li><li id="1I4PN6F2"></p><p></li><li id="1I4PN6F3"></p><p></li></ol><ol><li id="1I4PN6F4"></p><p id="1I4PN69B"></p><p></li><li id="1I4PN6F5"></p><p id="1I4PN69C"></p><p></li><li id="1I4PN6F6"></p><p id="1I4PN69D"></p><p></li><li id="1I4PN6F7"></p><p id="1I4PN69E"></p><p></li><li id="1I4PN6F8"></p><p id="1I4PN69F"></p><p></li><li id="1I4PN6F9"></p><p id="1I4PN69G"></p><p></li><li id="1I4PN6FA"></p><p id="1I4PN69H"></p><p></li><li id="1I4PN6FB"></p><p id="1I4PN69I"></p><p></li><li id="1I4PN6FC"></p><p id="1I4PN69J"></p><p></li><li id="1I4PN6FD"></p><p id="1I4PN69K"></p><p></li><li id="1I4PN6FE"></p><p id="1I4PN69L"></p><p></li><li id="1I4PN6FF"></p><p id="1I4PN69M"></p><p></li><li id="1I4PN6FG"></p><p id="1I4PN69N"></p><p></li><li id="1I4PN6FH"></p><p id="1I4PN69O"></p><p></li><li id="1I4PN6FI"></p><p id="1I4PN69P"></p><p></li><li id="1I4PN6FJ"></p><p id="1I4PN69Q"></p><p></li><li id="1I4PN6FK"></p><p id="1I4PN69R"></p><p></li><li id="1I4PN6FL"></p><p id="1I4PN69S"></p><p></li><li id="1I4PN6FM"></p><p id="1I4PN69T"></p><p></li><li id="1I4PN6FN"></p><p id="1I4PN69U"></p><p></li><li id="1I4PN6FO"></p><p id="1I4PN69V"></p><p></li><li id="1I4PN6FP"></p><p id="1I4PN6A0"></p><p></li><li id="1I4PN6FQ"></p><p id="1I4PN6A1"></p><p></li><li id="1I4PN6FR"></p><p id="1I4PN6A2"></p><p></li><li id="1I4PN6FS"></p><p id="1I4PN6A3"></p><p></li><li id="1I4PN6FT"></p><p id="1I4PN6A4"></p><p></li><li id="1I4PN6FU"></p><p id="1I4PN6A5"></p><p></li><li id="1I4PN6FV"></p><p id="1I4PN6A6"></p><p></li><li id="1I4PN6G0"></p><p id="1I4PN6A7"></p><p></li><li id="1I4PN6G1"></p><p id="1I4PN6A8"></p><p></li><li id="1I4PN6G2"></p><p id="1I4PN6A9"></p><p></li><li id="1I4PN6G3"></p><p id="1I4PN6AA"></p><p></li><li id="1I4PN6G4"></p><p id="1I4PN6AB"></p><p></li><li id="1I4PN6G5"></p><p id="1I4PN6AC"></p><p></li><li id="1I4PN6G6"></p><p id="1I4PN6AD"></p><p></li><li id="1I4PN6G7"></p><p id="1I4PN6AE"></p><p></li><li id="1I4PN6G8"></p><p id="1I4PN6AF"></p><p></li><li id="1I4PN6G9"></p><p id="1I4PN6AG"></p><p></li></ol><ol><li id="1I4PN6GA"></p><p id="1I4PN6AH"></p><p></li><li id="1I4PN6GB"></p><p id="1I4PN6AI"></p><p></li><li id="1I4PN6GC"></p><p id="1I4PN6AJ"></p><p></li><li id="1I4PN6GD"></p><p id="1I4PN6AK"></p><p></li><li id="1I4PN6GE"></p><p id="1I4PN6AL"></p><p></li><li id="1I4PN6GF"></p><p id="1I4PN6AM"></p><p></li><li id="1I4PN6GG"></p><p id="1I4PN6AN"></p><p></li><li id="1I4PN6GH"></p><p id="1I4PN6AO"></p><p></li><li id="1I4PN6GI"></p><p id="1I4PN6AP"></p><p></li><li id="1I4PN6GJ"></p><p id="1I4PN6AQ"></p><p></li><li id="1I4PN6GK"></p><p id="1I4PN6AR"></p><p></li></ol></p><p id="1I4PN6AS">上述代码经过两次跨域,值得注意的是浏览器向代理服务器发送请求,也遵循同源策略,最后在index.html文件打印出</p><p>6.nginx反向代理</p><p id="1I4PN6AT">实现原理类似于Node中间件代理,需要你搭建一个中转nginx服务器,用于转发请求。</p><p id="1I4PN6AU">使用nginx反向代理实现跨域,是最简单的跨域方式。只需要修改nginx的配置即可解决跨域问题,支持所有浏览器,支持session,不需要修改任何代码,并且不会影响服务器性能。</p><p id="1I4PN6AV">实现思路:通过nginx配置一个代理服务器(域名与domain1相同,端口不同)做跳板机,反向代理访问domain2接口,并且可以顺便修改cookie中domain信息,方便当前域cookie写入,实现跨域登录。</p><p id="1I4PN6B0">先下载nginx,然后将nginx目录下的nginx.conf修改如下:</p><p><ol><li id="1I4PN6GL"></p><p id="1I4PN6B1"></p><p></li><li id="1I4PN6GM"></p><p id="1I4PN6B2"></p><p></li><li id="1I4PN6GN"></p><p id="1I4PN6B3"></p><p></li><li id="1I4PN6GO"></p><p id="1I4PN6B4"></p><p></li><li id="1I4PN6GP"></p><p id="1I4PN6B5"></p><p></li><li id="1I4PN6GQ"></p><p id="1I4PN6B6"></p><p></li><li id="1I4PN6GR"></p><p id="1I4PN6B7"></p><p></li><li id="1I4PN6GS"></p><p id="1I4PN6B8"></p><p></li><li id="1I4PN6GT"></p><p></li><li id="1I4PN6GU"></p><p id="1I4PN6BA"></p><p></li><li id="1I4PN6GV"></p><p id="1I4PN6BB"></p><p></li><li id="1I4PN6H0"></p><p id="1I4PN6BC"></p><p></li><li id="1I4PN6H1"></p><p id="1I4PN6BD"></p><p></li><li id="1I4PN6H2"></p><p id="1I4PN6BE"></p><p></li></ol></p><p id="1I4PN6BF">最后通过命令行启动nginx</p><p><ol><li id="1I4PN6H3"></p><p id="1I4PN6BG"></p><p></li><li id="1I4PN6H4"></p><p id="1I4PN6BH"></p><p></li><li id="1I4PN6H5"></p><p id="1I4PN6BI"></p><p></li><li id="1I4PN6H6"></p><p id="1I4PN6BJ"></p><p></li><li id="1I4PN6H7"></p><p id="1I4PN6BK"></p><p></li><li id="1I4PN6H8"></p><p id="1I4PN6BL"></p><p></li><li id="1I4PN6H9"></p><p id="1I4PN6BM"></p><p></li></ol><ol><li id="1I4PN6HA"></p><p id="1I4PN6BN"></p><p></li><li id="1I4PN6HB"></p><p id="1I4PN6BO"></p><p></li><li id="1I4PN6HC"></p><p id="1I4PN6BP"></p><p></li><li id="1I4PN6HD"></p><p id="1I4PN6BQ"></p><p></li><li id="1I4PN6HE"></p><p id="1I4PN6BR"></p><p></li><li id="1I4PN6HF"></p><p id="1I4PN6BS"></p><p></li><li id="1I4PN6HG"></p><p id="1I4PN6BT"></p><p></li><li id="1I4PN6HH"></p><p id="1I4PN6BU"></p><p></li><li id="1I4PN6HI"></p><p id="1I4PN6BV"></p><p></li><li id="1I4PN6HJ"></p><p id="1I4PN6C0"></p><p></li><li id="1I4PN6HK"></p><p id="1I4PN6C1"></p><p></li><li id="1I4PN6HL"></p><p id="1I4PN6C2"></p><p></li><li id="1I4PN6HM"></p><p id="1I4PN6C3"></p><p></li><li id="1I4PN6HN"></p><p id="1I4PN6C4"></p><p></li><li id="1I4PN6HO"></p><p id="1I4PN6C5"></p><p></li></ol>7.window.name + iframe</p><p id="1I4PN6C6">window.name属性的独特之处:name值在不同的页面(甚至不同域名)加载后依旧存在,并且可以支持非常长的 name 值(2MB)。</p><p id="1I4PN6C7">其中a.html和b.html是同域的,都是;而c.html是</p><p><ol><li id="1I4PN6HP"></p><p id="1I4PN6C8"></p><p></li><li id="1I4PN6HQ"></p><p id="1I4PN6C9"></p><p></li><li id="1I4PN6HR"></p><p></li></ol></p><p id="1I4PN6CB">b.html为中间代理页,与a.html同域,内容为空。</p><p><ol><li id="1I4PN6HS"></p><p id="1I4PN6CC"></p><p></li><li id="1I4PN6HT"></p><p></li></ol></p><p id="1I4PN6CE">总结:通过iframe的src属性由外域转向本地域,跨域数据即由iframe的window.name从外域传递到本地域。这个就巧妙地绕过了浏览器的跨域访问限制,但同时它又是安全操作。</p><p>8.location.hash + iframe</p><p id="1I4PN6CF">实现原理: a.html欲与c.html跨域相互通信,通过中间页b.html来实现。 三个页面,不同域之间利用iframe的location.hash传值,相同域之间直接js访问来通信。</p><p id="1I4PN6CG">具体实现步骤:一开始a.html给c.html传一个hash值,然后c.html收到hash值后,再把hash值传递给b.html,最后b.html将结果放到a.html的hash值中。 同样的,a.html和b.html是同域的,都是;而c.html是</p><p><ol><li id="1I4PN6HU"></p><p id="1I4PN6CH"></p><p></li><li id="1I4PN6HV"></p><p id="1I4PN6CI"></p><p></li><li id="1I4PN6I0"></p><p></li></ol><ol><li id="1I4PN6I1"></p><p id="1I4PN6CK"></p><p></li><li id="1I4PN6I2"></p><p></li></ol><ol><li id="1I4PN6I3"></p><p id="1I4PN6CM"></p><p></li><li id="1I4PN6I4"></p><p id="1I4PN6CN"></p><p></li><li id="1I4PN6I5"></p><p id="1I4PN6CO"></p><p></li><li id="1I4PN6I6"></p><p id="1I4PN6CP"></p><p></li><li id="1I4PN6I7"></p><p id="1I4PN6CQ"></p><p></li></ol>9.document.domain + iframe</p><p id="1I4PN6CR"><strong>该方式只能用于二级域名相同的情况下,比如和适用于该方式</strong>。 只需要给页面添加表示二级域名都相同就可以实现跨域。</p><p id="1I4PN6CS">实现原理:两个页面都通过js强制设置document.domain为基础主域,就实现了同域。</p><p id="1I4PN6CT">我们看个例子:页面获取页面中a的值</p><p><ol><li id="1I4PN6I8"></p><p id="1I4PN6CU"></p><p></li><li id="1I4PN6I9"></p><p></li><li id="1I4PN6IA"></p><p id="1I4PN6D0"></p><p></li><li id="1I4PN6IB"></p><p id="1I4PN6D1"></p><p></li><li id="1I4PN6IC"></p><p></li><li id="1I4PN6ID"></p><p></li></ol><ol><li id="1I4PN6IE"></p><p id="1I4PN6D4"></p><p></li><li id="1I4PN6IF"></p><p></li><li id="1I4PN6IG"></p><p id="1I4PN6D6"></p><p></li><li id="1I4PN6IH"></p><p></li><li id="1I4PN6II"></p><p></li></ol>三、总结<ul><li id="1I4PN6IJ"></p><p id="1I4PN6D9">CORS支持所有类型的HTTP请求,是跨域HTTP请求的根本解决方案</p><p></li><li id="1I4PN6IK"></p><p id="1I4PN6DA">JSONP只支持GET请求,JSONP的优势在于支持老式浏览器,以及可以向不支持CORS的网站请求数据。</p><p></li><li id="1I4PN6IL"></p><p id="1I4PN6DB">不管是Node中间件代理还是nginx反向代理,主要是通过同源策略对服务器不加限制。</p><p></li><li id="1I4PN6IM"></p><p id="1I4PN6DC">日常工作中,用得比较多的跨域方案是cors和nginx反向代理</p><p></li></ul>参考文章<ul><li id="1I4PN6IN"></p><p id="1I4PN6DD">跨域资源共享 CORS 详解</p><p></li><li id="1I4PN6IO"></p><p id="1I4PN6DE">前端面试之道</p><p></li><li id="1I4PN6IP"></p><p id="1I4PN6DF">window.postMessage</p><p></li><li id="1I4PN6IQ"></p><p id="1I4PN6DG">前端常见跨域解决方案(全)</p><p></li><li id="1I4PN6IR"></p><p id="1I4PN6DH">深入跨域问题(4) - 利用代理解决跨域</p><p></li></ul></p><p id="1I4PN6DS">年度增速最快语言:Rust</p>

讯享网
小讯
上一篇 2025-04-19 21:06
下一篇 2025-04-25 22:50

相关推荐

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