前端跨域的几种方法

什么是跨域, 这边不做介绍

1.jsonp

这种方法是浏览器会借助script这个标签去访问其他服务器的资源, 达到传参的目的, 因为浏览器的script标签路径不会做拦截和校验. 一般前端会定义参数和回调函数, 然后组装到url上作为script.src, src指向的服务器会做处理, 执行回调函数并传值

// http://localhost:9990/jsonp.js
foo({ a: 1221 });
document.body.style.backgroundColor = "red";
<!-- http://localhost:8888/test.html-->
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>

  <body></body>

  <script>
    const foo = function (params) {
      alert(params);
    };
  </script>
  <script src="http://localhost:9990/jsonp.js"></script>
</html>

这样test.html中的就会alert({ a: 1221 })了, 这样就达到了跨域传参的效果, 也就是8888端口访问9990端口, 但是jsonp也可能造成xss攻击, 如果这个接口被别人, 也这样去用, 会导致本该信息泄露

2.cors

这个其实就是后端去处理了, 反正就是放开对服务器地址的访问, 不同域名也可以访问我, 比如那种完全放开的api就是这样, 对前端的访问不做限制

3.iframe + postMessage

比如a网站想和b网站做交互, 如何去实现呢, 可以用postMessage, a网站post 一个message, b网站进行一个监听, 然后处理a网站传输过来的值即可

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>我是a网站(http://localhost:999)</title>
  </head>

  <body>
    <div>
      <input id="text" type="text" value="Runoob" />
      <button id="sendMessage"></button>
    </div>
    <iframe
      id="receiver"
      src="http://127.0.0.1:5500/aaa.html"
      width="300"
      height="360"
    >
      <p>你的浏览器不支持 iframe</p>
    </iframe>
    <script>
      window.onload = function () {
        var receiver = document.getElementById("receiver").contentWindow;
        var btn = document.getElementById("sendMessage");
        btn.addEventListener("click", function (e) {
          e.preventDefault();
          var val = document.getElementById("text").value;
          receiver.postMessage(
            "Hello " + val + "!",
            "http://127.0.0.1:5500/aaa.html"
          );
        });
      };
    </script>
  </body>
</html>

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>我是b网站(http://127.0.0.1:5500/aaa.htm)</title>
    <style>
      body {
        background-color: red;
        width: 900px;
        height: 400px;
      }
    </style>
  </head>

  <body>
    <div id="recMessage"></div>
    <script>
      window.onload = function () {
        var messageEle = document.getElementById("recMessage");
        window.addEventListener("message", function (e) {
          // 监听 message 事件

          // alert(e.origin);
          if (e.origin !== "http://localhost:9991") {
            // 验证消息来源地址
            return;
          }
          messageEle.innerHTML = "从" + e.origin + "收到消息: " + e.data;
        });
      };
    </script>
  </body>
</html>

4. webpack 或者 nginx

其实这种我个人在本地开发用的比较多, 前后端分离的项目, 如果想访问后端的接口地址, 经常会碰到跨域的问题, 工程化的项目在wepack.config.js 或者 vue.config.js中的devServer.proxy配置一下后端地址即可

proxy:{
            //一旦devServer5000接到/api/xxx的请求,就会把请求转发到另一个服务器3000
            '/api':{
                //转发后的目标地址
                // target: project_config.proxyAddr,
                target:'localhost:3000',
                // 发送请求时,请求路径重写 /api/xxx ->  /xxx (去掉a/pi)
                pathRewrite: {
                    '^/api': ''
                }
            }
        }

但是比较小的项目怎么办, 类似jquery + layui这种, 根本用不上脚手架什么的, 可以用在本地下载一个nginx, 启动nginx.exe, 然后修改一下nginx.conf, 再nginx.exe -s reload即可, 例如以下配置会导致访问localhost: 9991/api/getUser => http://xxxxx.cn:8085/api/getUser, 达到跨域的目的

    server {
        listen       9991; // 本地开发端口, 可以开好多
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            root   C:\Users\xxxx\Desktop\demo; // 本地开发文件夹
            index  index.html  index.htm;
        }

        location /api { // 所有接口中带api的都会指向http://xxxxx.cn:8085/api
            
            proxy_pass http://xxxxx.cn:8085/api; 

        }
     }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值