概念

什么是同源策略

同源策略是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。
所谓同源是指:协议、域名、端口都相同

什么是跨域
跨域就是不同源,就是不满足协议、域名、端口都相同的约定
如:看下面的链接是否与 http://www.test.com/index.html 同源?

http://www.test.com/dir/login.html 同源
https://www.test.com/index.html 不同源 协议不同(https)
http://www.test.com:90/index.html 不同源 端口不同(90)
http://www.demo.com/index.html 不同源 域名不同(demo)

当协议、域名、端口中任意一个不相同时,就是不同源。若不同源之间相互请求资源,就算作跨域

跨域请求devServer代理几种配置

1:先在项目的根目录下新建 vue.config.js 文件
2:在module.exports内设置devServer来处理代理

假设我们要把http://localhost:8081/allin/policy/getProductInfo 中的域名换成 www.test.com 相当于把请求换成 http://www.test.com/allin/policy/getProductInfo

第一种代理方式

不设置 axios 的 baseURL 或者 赋值为空字符串

axios.defaults.baseURL = '';

请求的url地址为 /allin/policy/getProductInfo

  axios({
      ...
      url:'/allin/policy/getProductInfo',
      ...
  })

注意
请求的地址必须是包含 /allin ,但一定要注意 axios的baseURL 的配置,baseURL的配置会添加到每一个请求的 url 前面(下面的几种方式也是同样的)

 devServer: {
    proxy: {
        '/allin': {
            //要访问的跨域的域名
            target: 'http://www.test.com',
            ws: true, // 是否启用websockets
            secure:false, // 使用的是http协议则设置为false,https协议则设置为true
    	    //开启代理:在本地会创建一个虚拟服务端,然后发送请求的数据,并同时接收请求的数据,这样客户端端和服务端进行数据的交互就不会有跨域问题
            changOrigin: true,
        }
    }
}

相当于遇见 /allin 才做代理,则会把默认域名http://localhost:8081地址改成 target 对应的http://www.test.com地址,但是在浏览器的F12下,Network->Headers中看到还是http://localhost:8081/allin/policy/getProductInfo, 但是真正的请求的地址则是http://www.test.com/allin/policy/getProductInfo

注意
如果只是修改域名,则不需要写pathRewrite,但如果要写,则必须写成pathRewrite: {’^/allin’: ‘/allin’},相当于把/allin标识还替换成/allin

第二种代理方式

不设置 axios 的 baseURL 或者 赋值为空字符串

axios.defaults.baseURL = '';

请求的url地址为 /allin/getProductInfo

  axios({
      ...
      url:'/allin/getProductInfo',
      ...
  })

注意
这里请求时我没有写/polic,目的是在拦截跨域时我在 pathRewrite 上加上

devServer: {
    proxy: {
        '/allin': {
            //要访问的跨域的api的域名
            target: 'http://www.test.com',
            ws: true,
            secure:false, // 使用的是http协议则设置为false,https协议则设置为true
            changOrigin: true,
            pathRewrite: {
                '^/allin': '/allin/policy'
            }
        }
    }
}

相当于请求遇见 /allin 则替换成 /allin/policy注意/policy后边没有/,这样拼接成功才会是http://www.test.com/allin/policy/getProductInfo

第三种代理方式

不设置 axios 的 baseURL 或者 赋值为空字符串

axios.defaults.baseURL = '';

请求的url地址为 /allin/getProductInfo

  axios({
      ...
      url:'/allin/getProductInfo',
      ...
  })

注意
这里请求时我也没有写/polic,目的是在拦截跨域时我在 target 上加上

devServer: {
     proxy: {
         '/allin': {
             //要访问的跨域的api的域名
             target: 'http://www.test.com/allin/policy',
             ws: true,
             secure:false, // 使用的是http协议则设置为false,https协议则设置为true
             changOrigin: true,
             pathRewrite: {
                 '^/allin': '/'  //必须这样写
             }
         }
     }
 }

这里必须要写pathRewrite: { ‘^/allin’: ‘/’},而且里边必须要写成’^/allin’: ‘/’,这里的斜杠代表的意思就是使用target中的/allin/policy,否则就要使用 第二种代理方式 配置,如果不写pathRewrite则请求不会成功。

第四种代理方式(统一代理(推荐))

设置 axios 的 baseURL 值(任意)

axios.defaults.baseURL = '/api'

这样会为所有的 请求url 前面都加上 ‘/api’,方便做 统一代理

请求的url地址为 /allin/policy/getProductInfo

  axios({
      ...
      url:'/allin/policy/getProductInfo',
      ...
  })

真正发送的请求是:/api/allin/policy/getProductInfo

 devServer: {
     proxy: {
         '/api': {
             //要访问的跨域的域名
             target: 'http://www.test.com',
             ws: true,
             secure:false, // 使用的是http协议则设置为false,https协议则设置为true
             changOrigin: true,
             pathRewrite: {
                 '^/api': ''
             }
         }
     }
 }

相当于请求遇见 /api 才做代理,但真实的请求中没有/api,所以在pathRewrite中把 /api 去掉, 这样既有了标识, 又能在请求接口中把 /api 去掉

注意
pathRewrite:如果不写则只能修改代理的域名,如果写则可以修改代理的域名和后边的路径

proxy匹配规则

在 proxy 中可以写多个代理地址

  devServer: {
      proxy: {
          '/user': {
              //要访问的跨域的api的域名
              target: 'http://www.user.com',
              ws: true,
              secure:false,
              changOrigin: true,
          },
          '/order': {
              target: 'http://www.order.com',
              ws: true,
              secure:false,
              changOrigin: true,
          },
          '/pay': {
              target: 'http://www.pay.com',
              ws: true,
              secure:false,
              changOrigin: true,
          },
      }
  }

proxy 的匹配规则是根据正则匹配 如上 /user、/order、/pay 如果 请求地址 包含 此字符串,就算匹配成功,一旦匹配成功就 不会 继续向下匹配
如:

  • 请求 /user/info 则匹配 target 为 http://www.user.com
  • 请求 /order/user/list 则匹配 target 也为 http://www.user.com
  • 请求 /order/pay/user/list 则匹配 target 也为 http://www.user.com
  • 请求 /pay/order/list 则匹配 target 为 http://www.order.com

如果我们需要以 某个路径开头 才算 匹配成功,则可以改成'^/user'、'^/account'、'^/pay'

使用场景

通过 devServer 设置的代理只适合在 本地环境 使用,即通过代理把请求发送到目标服务器上,如果发布到线上,则会提示 404 路径未找到。

解决线上环境跨域问题

  1. 前端先按 第四种代理方式 做统一代理
  2. 后端 nginx 反向代理配置

或者参考

vue-cli3.0动态配置开发,测试,线上环境

Logo

前往低代码交流专区

更多推荐