前端跨域解决方案

75 阅读3分钟

引言:克服ajax同源策略就是跨域,同源策略是一种约定,是为了防止浏览器受到XSS、CSFR等攻击。协议域名或者端口号三者不同,就会产生跨域。

一、JSONP跨域:

  • jsonp是一种非正式传输协议,原理就是利用<script>标签没有跨域限制,通过<script>标签src属性,发送带有回调参数的get请求,服务端接口将返回数据拼凑到回调函数中,由浏览器解析从而拿到数据。
  • jsonp的缺点:只能发送get请求
<script>
  var script = document.createElement('script');

  // 传参的时候将回调函数名给后端,方便后端返回时执行这个在前端定义的回调函数
  script.src =
    'http://www.domain2.com:8080/login?user=admin&callback=handleCallback';
  document.head.appendChild(script);

  // 回调执行函数
  function handleCallback(res) {
    // 服务端返回的是json格式的数据
    alert(JSON.stringify(res));
  }
</script>    

二、CORS跨域

  • CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)
  • CORS需要浏览器和服务器同时支持,整个 CORS通信过程,都是浏览器自动完成不需要用户参与,通过添加一些附加的头信息解决跨域
  • IE10以下不兼容

三、代理服务器客户端=>代理服务器=>服务器

1、脚手架配置代理:!!! 单个代理的配置和多个代理的配置不能同时存在

  • 1.配置单个代理
    • (1)优点:配置简单,请求资源时直接发给前端即可。
    • (2)缺点:不能配置多个代理,不能灵活的控制请求是否走代理。
    • (3)工作方式:若按照上述配置代理,当请求了前端不存在的资源时,那么该请求会转发给服务器 (优先匹配前端资源)
    • (4)资源前端存在,就不会再将请求转发给服务器了

vue-cli 脚手架在 vue.config.js 中添加如下配置

module.exports = {
  devServer: {
    proxy: '协议://域名:端口号'; // 代理目标的基础路径
  }
}

create-react-app 脚手架在package.json中追加如下配置

"proxy":"协议://域名:端口号"
  • 2.配置多个代理
    • (1)优点:可以配置多个代理,且可以灵活的控制请求是否走代理。
    • (2)缺点:配置略微繁琐,请求资源时必须加前缀。
    • (3)在发送请求时的地址中加入标识,例如:'协议://域名:端口号/标识/请求的文件路径'
      ('http://localhost:8080/api1/index.html')

vue-cli 脚手架在 vue.config.js 中添加如下配置

module.exports = {
  devServer: {
    proxy: {
      '/api1': {
        // 匹配所有以 '/api1'开头的请求路径
        target: '协议://域名:端口号', // 代理目标的基础路径1
        changeOrigin: true,
        // 匹配完成后将路径中的前缀去除,将路径修改成原本的资源路径
        pathRewrite: { '^/api1': '' },
        // ws: true, //用于支持websocket
        // changeOrigin: true //用于控制请求头中的host值
      },
      '/api2': {
        // 匹配所有以 '/api2'开头的请求路径
        target: '协议://域名:端口号', // 代理目标的基础路径2
        changeOrigin: true,
        pathRewrite: { '^/api2': '' },
      },
      // 其他需要代理的服务器
    },
  },
};
/*
   changeOrigin设置为true时,服务器收到的请求头中的host为真实值:localhost:5000
   changeOrigin设置为false时,服务器收到的请求头中的host为假值:localhost:8080
   changeOrigin默认值为true
*/

create-react-app 脚手架在src文件夹新建配置文件:src/setupProxy.js

const proxy = require('http-proxy-middleware');

   module.exports = function (app) {
     app.use(
       proxy('/api1', {
         // 匹配所有以 '/api1'开头的请求路径
         target: '协议://域名:端口号', // 代理目标的基础路径1
         changeOrigin: true, //控制服务器接收到的请求头中host字段的值
         // changeOrigin设置为true时,服务器收到的请求头中的host为:localhost:5000
         // changeOrigin设置为false时,服务器收到的请求头中的host为:localhost:3000
         // changeOrigin默认值为false,但我们一般将changeOrigin值设为true 
         pathRewrite: { '^/api1': '' }, //去除请求前缀,保证交给后台服务器的是正常请求地址(必须配置)
       }),
       proxy('/api2', {
         // 匹配所有以 '/api2'开头的请求路径
         target: '协议://域名:端口号', // 代理目标的基础路径2
         changeOrigin: true,
         pathRewrite: { '^/api2': '' },
       })
     );
   };