vue前端跨域问题


一、跨域分类
  跨域分为开发跨域(开发环境跨域)和线上跨域(生产环境跨域):

  • 开发环境跨域:开发阶段前后端工作站不同,所以ip地址不同,请求数据必然出现跨域问题;
  • 生产环境跨域:一个网站关联多台服务器产生的跨域问题,构成一个完整的生产服务器集群,生产服务器集群之间的通信通过地址的方式通信,就算在局域网中,端口地址也是不一样的。

二、解决
2.1 线上跨域
  线上跨域的常规解决方案:

  • 后端代码上增加一个跨域请求响应头:Access-Control-Allow-Origin

   例如:php中的header(Access-Control-Allow-Origin:*)     ;PS:其中,*表示所有请求地址都可允许跨域响应

  • 也可以采用 前后端配置处理 的方式:采用jsonp模式,前端完成jsonp请求发送

2.2 开发跨域

  即:在开发过程中存在的跨域问题,这种现象一般出现在 前后端分离的项目中:前后端分离导致开发联调过程中不在同一服务器或端口下,引发的跨域。

  开发阶段引发的跨域可能在项目上线时消失,即当前端代码打包到后端同一服务器上,此时地址相同端口相同,相当于所有的接口都是在同一服务器内部进行请求调用操作,因此便不会产生跨域。但是呢,没有开发哪儿来的上线,因此还是免不了开发过程中的跨域。

  解决方式:前端构建代理服务器来完成跨域。即:在本地创建一个虚拟服务器,发送请求数据,同时接收请求的数据

  过程:

  1.  在vue.config.js配置文件中,通过devServer.proxy选项配置代理:
    devServer:{
      port: 8080,
      proxy: {
          // key:描述项目中哪些请求需要被代理服务器代理,以路径前缀方式描述key,定义被拦截请求的前缀
          "/api": {
              target: "http://127.0.0.1:8080", // 定义被拦截的请求需要访问的真实服务器
              pathRewrite: { // 通过前缀替换进行地址的重写和定义:去掉/api(因为/api默认会拼接上去)
                "^/api": "" // 替换掉以/api开头的,这里用空字符串替换,直接去掉
              }
          }
      }
    }

    原理:当遇到“/api”时,会进入内部函数,将target变量的真实后台地址拼接到“/api”的前面,此时 请求路径变成了:“http://127.0.0.1:8080/api",然后由于pathRewrite方法中将 “/api”替换成了空,也就是说直接去掉,因此路径变成了 ““http://127.0.0.1:8080”,这就完成了代理,通过“/api”这个桥梁将后台地址成功地引入。

    注:
    vue.config.js文件只是做前端代理解决跨域问题时所用到的配置文件,当前端打包到服务器上时,该文件会被忽略,因此前端对于 api接口路径的定义一定要跟后端所提供的保持一致,不能随意增减上下文,即使你可能通过 配置代理 获取了正确的请求路径,因为打包到服务器后代理便失效了。

三、实例

1、当前需请求的后端接口路径:

192.168.88.88:8091/host/getHostsInfo

2、配置文件

devServer:{
  port: 8080,    //代表本地服务器启动后的虚拟端口
  proxy: {
      "^/host": {    // ^/host 表示匹配查询以host开头的路径, /host有可能查询到路径中包含host的,不一定作为开头
          target: "http://192.168.88.88:8091", // 定义被拦截的请求需要访问的真实服务器
          pathRewrite: { // 通过前缀替换进行地址的重写和定义:去掉/host(因为/host默认会拼接上去)
            "^/host": "/host" // 替换掉以/host开头的,这里只是为了展示pathRewrite的用法,不需替换可以直接去掉这段。
          }
      }
  }
}

 3、创建axios的时候,baseUrl配置:

const ajax = axios.create({
    baseURL:"",
    timeout: 6000,//请求超时时间
})

创建请求:

export function getData() { //get
  return request({
    url: '/host/getHostsInfo',
    method: 'GET'
  })
}

此时,baseUrl拼上请求地址,得到:/host/getHostsInfo,在代理proxy函数中,遇到 /host,则代理到target下的真实服务器路径,将target的真实服务器地址加到 /host 前面,因此得到:http://192.168.88.88:8091/host/getHostsInfo ,也就是真实需请求的后端真实服务器接口路径地址。

而如果在pathRewrite中对路径进行了重写,将 /host 替换成 "" 空字符串,即去掉它,此时代表后端接口请求路径:http://192.168.88.88:8091/getHostsInfo。当然,本实例中这样的代理是调不通的~

 

四、当项目需请求不同的后端地址时候,可配置多个代理。

原理一样,直接上代码:

    proxy:{
      "/api": {
          target: "http://192.168.88.88:8091", 
          // ws: true, // 是否启用websockets
          changeOrigin: true
          pathRewrite: {
              "^/api": ""
          }
      },
      "/user": {
          target: "http://192.168.99.99:8091",
          // ws: true, 
          changeOrigin: true
          pathRewrite: {
              "^/user": ""
          }
      },
   
  }, 

baseUrl配置:

const ajax = axios.create({
    baseURL:"/",    //注意:这里我baseUrl写的是 / ,因此在请求接口里的url没有以 / 开头了,写法随意,原理就是一个拼接过程。
    timeout: 6000,//请求超时时间
})

请求接口:

export function getData() { //get
  return request({
    url: 'api/host/getHostsInfo',
    method: 'GET'
  })
}
export function getData1() { //get
  return request({
    url: 'user/host/getHostsInfo',
    method: 'GET'
  })
}

此时,上面两种方式最终请求的真实服务器接口路径 是 两台服务器下的同一接口路径:

http://192.168.88.88:8091/host/getHostsInfo
http://192.168.99.99:8091/host/getHostsInfo


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM