• js -- 跨域问题


     

    前言

      出于浏览器同源策略的影响,浏览器会阻止一个域的 js 脚本和另一个域的内容进行交互,因此产生了跨域问题,该问题也经常在面试和开发中遇到,本文来总结一下相关知识点。

    正文

      1、什么是同源策略

      因为浏览器出于安全考虑,存在同源策略,就是说如果协议、域名、端口号有一个不同就产生了跨域,不同域之间的资源是不能交互的,比如:Ajax 请求别的域的资源就会失败,无法读取别的域中网页的 Cookie 、LocalStorage 和 IndexedDB,无法获取别的域中网页中的 DOM 对象等。下面总结了跨域常见的解决方法。

      2、跨域解决方法

      (1)JSONP 解决跨域

      JSONP 是服务器与客户端跨源通信的常用方法。最大特点就是简单适用,兼容性好(兼容低版本IE),缺点是只支持get请求,不支持post请求。

    核心思想:网页通过添加一个<script>元素,向服务器请求 JSON 数据,服务器收到请求后,将数据放在一个指定名字的回调函数的参数位置传回来。

    复制代码
      <script type="text/javascript">
        // 创建jsonp 函数
        function jsonp(url, data, callback) {
          var id = "_" + "Json" + (new Date()).getTime();  //创建一个几乎唯一的id
          window[id] = function (result) {
            if (callback) {
              callback(result);
            }
            var getId = document.getElementById(id);  //移除Script标签和id
            getId.parentNode.removeChild(getId);
            window[getId] = null;  //调用函数后进行销毁
          }
          url = url.replace("callback=?", "callback=" + id);
          const script = document.createElement('script')
          script.src = url
          script.id = id
          script.async = true
          script.type = 'text/javascript'
          document.body.appendChild(script)
        }
        // 创建回调函数
        function dosomething(res) {
          console.log(res.data)
        }
        // 调用jsonp函数
        jsonp('http://test.com/api/getInfo?callback=?', dosomething)
      </script>
    复制代码

      (2)document.domain 解决跨域

      浏览器通过 document.domain 属性来判断两个页面是否同源,因此可以设置相同的 document.domain 属性值来解决跨域,缺点该方法只限于主域相同,子域不同的跨域场景。

        // a.html
        document.domain = "test.com"
        // b.html
        document.domain = "test.com"

      (3)postMessage Api 解决跨域

      通常用于获取嵌入页面中的第三方数据,一个页面发送消息,另一个页面接收消息,比如通过 iframe 标签嵌入的父子页面之间的消息传值。

    复制代码
        <!-- 父页面 -->
        <iframe src="child.html" frameborder="0" id="Iframe"></iframe>
        <script>
          // 监听子页面传递的值
          window.addEventListener('message', function (event) {
            
          })
          // 给子页面发消息
          document.getElementById('Iframe').contentWindow.postMessage(message, "*")
        </script>
        <!-- 子页面 -->
        <script>
          // 子页面给父页面发消息
           window.parent.postMessage("给父页面发消息", '*')
          //  监听父页面的消息
           window.addEventListener('message', function (event) {
          })
        </script>
    复制代码

      (4)CORS 解决跨域

      该方式需要服务端和浏览器同时支持,浏览器会自动进行 CORS 通信,后端实现了 CORS 就实现了跨域,服务端需要设置 Access-Control-Allow-Origin 就可以开启 CORS ,该属性表示哪些域名可以访问资源,如果使用通配符则表示所有网站都可以访问。

      如果要实现带 Cookie 进行跨域请求,前端需要额外设置 withCredentials 为 true。

      (5)Nginx 反向代理

      该方法需要通过 Nginx 搭建中转服务器,用于转发请求。只需要在 nginx.config 中配置转发请求即可。

      (6)webpack-dev-server 设置本地代理

      该方式用于开发环境中,在webpack.config.js 中设置代理的本地服务器就可以,如下:

    复制代码
    devServer: {
            port: 8080,
            proxy: {
                "/api": {
                  target: "http://192.168.25.20:8088" // 后端接口
                }
            }
        }
    复制代码

    写在最后

      以上就是本文的全部内容,希望给读者带来些许的帮助和进步,方便的话点个关注,小白的成长之路会持续更新一些工作中常见的问题和技术点。

     

     

     

     

  • 相关阅读:
    【mcuclub】独立按键
    【Azure】构建安全架构的 Azure 云:深入了解零信任体系结构
    如何实现在本地 Linux 主机上实现对企业级夜莺监控分析工具的远程连接
    正点原子嵌入式linux驱动开发——Linux LCD驱动
    Java实现卡方检验
    Java 栈帧的一个面试题
    2.10 Go语言中的注释、关键字、内置函数和操作符
    EN 14351-1窗和外部行人门—CE认证
    hadoop3.x入门到精通-阶段六(深入Hadoop源码达到定制化阶段)
    [环境配置][原创]matconv在windows上GPU编译成功的环境
  • 原文地址:https://www.cnblogs.com/zaishiyu/p/15554962.html