跨域及解决方案 正反向代理区别(一篇搞定)

1,137 阅读4分钟

跨域

  • 同源策略的原因

什么是同源策略

  • 同源策略/SOP(Same origin policy)是一种约定,由Netscape公司1995年引入浏览器,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,浏览器很容易受到XSS、CSFR等攻击。

    • 所谓同源是指"协议+域名+端口"三者相同,即便两个不同的域名指向同一个ip地址,也非同源。
    • 同源策略限制以下几种行为: (1)Cookie、LocalStorage 和 IndexDB 无法读取 (2)DOM 和 Js对象无法获得 (3)AJAX 请求不能发送
  • 浏览器采用同源策略,禁止页面加载或执行与自身来源不同的域的任何脚本。换句话说浏览器禁止的是来自不同源的"document"或脚本,对当前"document"读取或设置某些属性。
  • 情景:

    • 比如一个恶意网站的页面通过iframe嵌入了银行的登录页面(二者不同源),如果没有同源限制,恶意网页上的javascript脚本就可以在用户登录银行的时候获取用户名和密码。

解决方案

jsonp

  • 原理

    • 动态生成 script 标签来加载资源
    • 因为其中的 src 属性 浏览器是不拦截的
  • 缺点

    • 只支持 get 请求 不支持 post

    • 请求第三方数据的时候 cdn

      • 也能提高性能
      • 脚本下载速度 打包体积减小
  • link img script 都能跨域

    • img标签不能访问服务器返回的响应内容,也就是说只能单向的发送get请求

    • 使用script标签实现的jsonp跨域可以将服务器响应文本以函数参数的形式返回,浏览器解析js代码时直接就执行了

    • 实现:

      • <script>
                function showFlightInfo(data){
                    var flightNoEle = document.createElement('h4');
                    flightNoEle.innerHTML=data.flightNo;
        ​
                    var fromEle = document.createElement('h4');
                    fromEle.innerHTML=data.from;
        ​
                    var toEle = document.createElement('h4');
                    toEle.innerHTML=data.to;
        ​
                    document.body.appendChild(flightNoEle);
                    document.body.appendChild(fromEle);
                    document.body.appendChild(toEle);
                }
        </script>
        <script src="http://localhost:3001/info/flight?flightNo=MU531&callbackFunc=showFlightInfo"></script>
        

CORS 跨域资源共享

  • 就是在服务端进行配置 加一个响应头

    • 工作中经常使用
    • res.header('Access-Control-Allow-Origin', '*')

服务器代理

  • 浏览器不允许跨域 为了安全

  • 正向代理和反向代理都是通过代理服务器完成的 只是他们面向的对象不一样

    • 下面详细解释

中间服务器代理

  • 前端部署地址:127.0.0.1:8000
  • 中间服务器:127.0.0.1:8000
  • 后端服务器目标地址:127.0.0.1:8888

为什么使用中间服务器就行了呢

  • 因为浏览器向服务器请求会有跨域问题

    • 但是服务器向服务器请求是没有跨域问题的
  • 所以后端配置一台中间服务器 然后该服务器向目标服务器请求资源

正向代理

  • 简单的说 正向代理就是面向客户端的

  • 如上面中间代理服务器所说 比如 client A 通过代理服务器 向 服务器 B 请求到了资源并返回

    • 客户 A 觉得好用 就向好友 client B C D 推荐使用 好友 client B C D 也通过该代理服务器 向 Sever B 请求到了资源
    • 那么 Sever B 只知道代理服务器向他发送了请求 而不知道客户是谁
    • 代理服务器是面向 客户端的 这就是正向代理

nginx 反向代理

  • 简单的说 反向代理是面向服务端的

  • 比如 client A 向代理服务器发送了第一次请求 代理服务器向 Sever B 请求到了资源并返回 client A 向代理服务器发送了第二次请求 代理服务器向 Sever C 请求到了资源并返回 ...

    • client A 只知道 代理服务器向他返回资源 并不在乎请求的资源来自哪里
    • 代理服务器是面向 服务器的 这就是反向代理
  • baseUrl = '/api'
    baseUrl = '本地服务器地址 + /api'
    
  • server: {
        proxy: {
          // 用来标识哪些 接口需要跨域 使用了 api 的就会跨域
          '/api': {
            // 目标服务器地址 target + baseUrl + 路径
            target: 'http://123.207.32.32:8000/',
            // 开启代理:在本地创建一个虚拟服务器 然后这个服务器向目标服务器请求资源
            // 而浏览器请求这个本地的是同源的 不会跨域
            changeOrigin: true,
            // 这个用来去除 api
            rewrite: (path) => path.replace(/^/api/, ''),
          },
        },
      },
    

正向代理与反向代理的区别

  • 前面理解了就知道了

  • 核心就在于

    • 正向代理是代理客户端
    • 反向代理是代理服务器
  • 代理哪端便可以隐藏哪端

    • 正向代理隐藏真实客户端
    • 反向代理隐藏真实服务端
  • 总结

    • 正向代理为客户端服务
    • 反向代理为服务器端服务