阅读 1716

如何解决Vue中Axios跨域请求的问题

开发环境

配置

我们在vue项目中使用axios请求接口时可能会遇到跨域的问题,要解决跨域问题,需要先在配置文件vue.config.js里添加以下代码:

//配置axios跨域请求
    devServer: {
        proxy: {
            '/api': { //访问路径,可以自己设置,
                target: 'http://localhost:8081', //代理接口,即请求的url的前缀
                changeOrigin: true, //设置是否跨域,开启代理:在本地会创建一个虚拟服务端,然后发送请求的数据,并同时接收请求的数据,这样客户端端和服务端进行数据的交互就不会有跨域问题
                ws: true, // 是否启用websockets
                pathRewrite: { //访问路径重写
                    '^/api': ''
                }
            }
        }
    }
复制代码

修改完配置文件后,一定要记得重启项目,否则修改不会生效!

请求

重启项目后,就可以使用axios请求后台接口了:

axios("/api/activity").then((res)=>{
      console.log(res)
 })
复制代码

这里调用请求时请求的url地址是/api/activity,而实际请求的是http://localhost:8081/activity,如果你不想每次请求都带上/api,那么你可以在main.js中添加以下代码:

axios.defaults.baseURL = "/api";
复制代码

这段代码会在你每次请求的url前加上/api的前缀,这样我们可以再修改一下上面的代码:

axios("activity").then((res)=>{
      console.log(res)
})
复制代码

至此,完成以上配置后就可以解决开发环境下的跨域问题。

线上环境

因为项目打包发布后的线上环境没有devServer,所以请求的url不会重写,因此上线后会报接口404的错误。

我们可以通过判断请求的环境是本地还是线上,动态的添加请求url前缀,以解决上述问题。

//判断开发环境是本地还是线上 true是本地 false是线上
//保存url 如果是本地 则url前缀为/api 如果是线上 则url前缀为线上api地址
let url = process.env.NODE_ENV == "development" ? "/api" : "http://api.yinbaole.com/";
复制代码

这时我们再修改一下以上的代码:

axios.defaults.baseURL = url;
复制代码

这样就解决了线上环境下请求接口404的问题。

同样因为线上环境下没有devServer的原因,上面写的代理解决跨域的方案已经失效,这时如果项目和api地址不在同一服务器下或者因为域名、协议等的原因产生跨域,那么跨域的问题依然会出现。

这时参考axios官方文档,以application / x-www-form-urlencoded格式发送数据就可以解决此问题。

配置

在vue项目里创建axios.js文件,路径自定,写入以下代码。下面的代码整合了上面判断开发环境的片段,目的是使main.js里的代码更加简练。

import Axios from "axios";
//引入qs库
import qs from "qs";
//判断开发环境是本地还是线上 true是本地 false是线上
//保存url 如果是本地 则url前缀为/api 如果是线上 则url前缀为线上api地址
let url = process.env.NODE_ENV == "development" ? "/api" : "http://api.yinbaole.com/";
const axios = Axios.create({
  //以application / x-www-form-urlencoded格式发送数据
  headers: {
    "content-type": "application/x-www-form-urlencoded",
  },
  //带cookie请求
  withCredentials: true,
});
//给每个url添加默认前缀
axios.defaults.baseURL = url;

//请求拦截
axios.interceptors.request.use((config) => {
  //如果发送的数据本身就是FormData格式的数据 那么就不需要用qs模块进行转换
  if (typeof config.data == "object" && config.data.__proto__.toString() == "[object FormData]") return config;
  if (config.method == "post") {
    //如果是post请求 使用qs模块转换发送的数据
    config.data = qs.stringify(config.data);
  }
  return config;
});
export default axios;
复制代码

配置完成后,在main.js中将引入axios的路径更改为创建好的axios.js文件路径即可,项目中已经写好的请求无需进行任何改动。

以上,完成配置后即可解决vue项目开发环境及线上环境axios请求的跨域问题。

参考

devServer之proxy跨域

Vue使用axios实现跨域请求

vue 使用axios 出现跨域请求的两种解决方法

axios官方文档

跨源资源共享(CORS) - HTTP | MDN

文章分类
前端
文章标签