写点什么

跨域的问题终于能解决了

  • 2022 年 7 月 09 日
  • 本文字数:2025 字

    阅读完需:约 7 分钟

0.写在最前

啊😭!在我大一学习前端,刚入门的时候,尝试着用 jquery 做一些小项目,这个东西困扰了我一个寒假!!!!当时没有跨域这个概念,于是乎就开始疯狂的百度。。。。为了不拖进度,把一个前后端分离的项目被逼成了不分离,后来还好,在开学前夕顺利解决,把不分离的“不”字去掉了,并也按时完成了项目!!!


(拖了一个月左右应该也叫按时完成吧,不管了,先奖励自己一个🍗~)


跨域问题真的成了我一段时间的心里阴影,后来一谈到跨域,心里贼怕!


最近复习网络部分,刷到了跨域的知识点,于是结合自己毕生所学(加上搜集的一丢资料),总结了一些关于跨域的知识。

1. 什么是跨域?

先举个栗子🌰,我博客的网址是:https://blog.wangez.site:8080


最前面的 https 叫做协议,随后的 blog.wangez.site 叫做域名,最后的 8080 叫做端口号


(注:真实的博客网址不带 8080,我的博客,都说了是举个栗子🌰,不会有人当真了吧!!!)。


当前页面中的某个接口请求的地址和当前页面的地址如果协议、域名、端口其中有一项不同,就说该接口跨域了

2. 为什么有跨域?

浏览器为了保证网页的安全,出的同源协议策略


这部分以下摘录自 MDN,想详细了解这部分可以去[MDN](浏览器的同源策略 - Web 安全 | MDN (mozilla.org))上看看。


同源策略是一个重要的安全策略,它用于限制一个 origin 的文档或者它加载的脚本如何能与另一个源的资源进行交互。它能帮助阻隔恶意文档,减少可能被攻击的媒介。


如果两个 URL 的 protocol、port (en-US) (如果有指定的话)和 host 都相同的话,则这两个 URL 是同源。这个方案也被称为“协议/主机/端口元组”,或者直接是 “元组”。(“元组” 是指一组项目构成的整体,双重/三重/四重/五重/等的通用形式)。


下表给出了与 URL http://store.company.com/dir/page.html 的源进行对比的示例:


3. 跨域报错


当我们测接口的时候,看见数据并没有如约而至,打开我们万能的浏览器控制台,看见了这个报错,不要犹豫,就是遇见了跨域问题!

4. 跨域解决办法

4.1 cors

这是我目前写项目最常用的一种解决办法,也是当下最流行的方案,通过设置后端,来解决跨域,简单快捷


传说中的后端跨域!


res.setHeader('Access-Control-Allow-Origin', '*'); // 允许跨域的源地址是什么,可以设置为*,也可以设成你的源地址
res.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); // 设置返回数据类型
res.setHeader("Access-Control-Allow-Methods", "GET, PUT, OPTIONS, POST"); // 控制哪种请求是可以跨域的
res.setHeader("Access-Control-Allow-Credentials", true); // 跨域的时候是否携带cookie
复制代码

4.2 jsonp

利用的原理是 script 标签可以跨域请求资源,将回调函数作为参数拼接在 url 中


传说中的前端跨域!但是需要后端的小伙伴们来配合我们一下哦🙄


​ 后端收到请求,调用该回调函数,并将数据作为参数返回去,注意设置响应头返回文档类型,应该设置成 javascript


res.setHeader('content-type', 'application/javascript') // 要注意不要忘了设置这个 ,否则会出错误!


  <script>        function JsonpCallback(data) {              // 在这里处理后端返回来的data数据              console.log(data);          }    </script>    <script src="http://127.0.0.1:12345/jsonp/callback=JsonpCallback"></script>
复制代码

4.3 postmessage

这个是我没听说过的一种方法,它是利用 html5 的 api 进行的,具有特定的使用场景。


使用场景:一个页面中嵌入另一个 iframe 页面,


​ 在主页面中使用 postmessage 发送数据,在 iframe 页面中用监听器接收数据


       // 主页面       iFrame.onload = function () {         iFrame.contentWindow.postMessage({ msg: 'MessageFromIndexPage' }, '\*');       }       // iframe页面       window.addEventListener("message", function (event) {                console.log('这里是接收到来自父页面的消息,消息内容在event.data属性中', event)              }, false)
复制代码

4.4 其他方法:node 中间件、nginx 反向代理、websocket 等

主要是因为同源策略是浏览器的限制,服务器和服务器之间没有限制


这次我们举个菠萝🍍,小红想要小绿的新玩具 (发出接口请求),但是小绿不给他 (同源策略),于是小红去找了小兰,对小兰说,我想要小绿的新玩具 (准备去搞中间件进行转发或者做代理了),小兰去跟小绿要来了新玩具 (拿到了想要的数据,说明方法成功),并将新玩具交给了小红 (解决了跨域)


在这里面我只接触过 node 中间件跟 nginx 反向代理,也不算很深入的了解,所以就先不献丑啦,等日后学有所成再来填上这个坑!

5.最后

跨域是很常见的一个问题,也是出现在面试问题中频率比较高的问题,希望每个小伙伴们在遇到这个问题的时候都能顺利解决。虽然我们现在写项目的时候,框架中大都为我们配置了代理(Vue 的 proxyTable 代理等),但是我想了解其根源对于我们的自我提高是非常有帮助的!

发布于: 刚刚阅读数: 2
用户头像

公众号:前端成长日记 2021.08.09 加入

还未添加个人简介

评论

发布
暂无评论
跨域的问题终于能解决了_7月月更_是乃德也是Ned_InfoQ写作社区