开发中遇到的跨域的问题终于能解决了

举报
是乃德也是Ned 发表于 2022/09/02 15:44:26 2022/09/02
【摘要】 0.写在最前啊😭!在我大一学习前端,刚入门的时候,尝试着用jquery做一些小项目,这个东西困扰了我一个寒假!!!!当时没有跨域这个概念,于是乎就开始疯狂的百度。。。。为了不拖进度,把一个前后端分离的项目被逼成了不分离,后来还好,在开学前夕顺利解决,把不分离的“不”字去掉了,并也按时完成了项目!!!(拖了一个月左右应该也叫按时完成吧,不管了,先奖励自己一个🍗~)跨域问题真的成了我一段时...

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 的源进行对比的示例:

URL 结果 原因
http://store.company.com/dir2/other.html 同源 只有路径不同
http://store.company.com/dir/inner/another.html 同源 只有路径不同
https://store.company.com/secure.html 失败 协议不同
http://store.company.com:81/dir/etc.html 失败 端口不同 ( http:// 默认端口是80)
http://news.company.com/dir/other.html 失败 主机不同

3. 跨域报错

image-20210605180026687

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

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代理等),但是我想了解其根源对于我们的自我提高是非常有帮助的!

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。