Vue中Axios的详细使用及跨域解决

Vue中Axios的详细使用及跨域解决
强烈推介IDEA2020.2破解激活,IntelliJ IDEA 注册码,2020.2 IDEA 激活码

1.安装

安装命令:cnpm install axios --save

2.配置

在项目src目录中新建axios/index.js文件,用以专门抽取配置axios。
axios/index.js

import axios from 'axios';

// axios 配置
var instance = axios.create({
   
  headers:{
   
    post:{
   'Content-Type':'application/x-www-form-urlencoded;charset=utf-8'}	//post请求头
  },
  timeout: 10000,	//请求超时时间
  baseURL: 'http://127.0.0.1:8081',   //请求默认地址
  withCredentials: true //允许请求携带cookie信息
});


// 添加请求拦截器
instance.interceptors.request.use(
  config => {
   // 在发送请求之前做些什么,比如传token
  return config
}, error => {
   // 对请求错误做些什么
  console.log(error) // for debug
  return Promise.reject(error);
})

// 添加响应拦截器
instance.interceptors.response.use(
  response => {
   //对请求响应做点什么

    return response;
  }, error => {
   // 对响应错误做点什么
    console.log('err' + error);  // for debug
    if (error.response){
   
      return Promise.reject(error);
    }
    switch (error.response.status) {
   
      case 401:{
   //401没有权限做点什么
        console.log('登录失效,请重新登录');
        break;
      }
      case 403:{
   // 返回 403 没有资格访问
        console.log('没有访问权限');
        break;
      }
      default:{
   
        console.log('其他错误处理');
      }
    }
  });

export default instance;

3.引入

在main.js中引入方法:

import axios from './axios';
Vue.prototype.$axios = axios;

4.请求方式

Get、Delete请求:

这类请求也称作query请求。第一种方式为拼接url的形式传参,不推荐:

axios.get('/user?username=korbin&password=12345')
.then(function (res) {
   
    console.log(res);
}).catch(function (err) {
   
    console.log(err);
});

第二种方式是封装到params中,推荐:

axios.get('/user', {
     //params参数必写 , 如果没有参数传{}也可以
    params: {
     
       username: 'korbin',
       password: '123456'
    }
})
.then(function (res) {
   
    console.log(res);
})
.catch(function (err) {
   
    console.log(err);
});
Post、Put、Patch请求

第一种传参方式,通过FormData对象:

var formData=new FormData();
formData.append('username','korbin');
formData.append('password','123456');
 
axios.post("/login",formData)
     .then((res) => {
   return res})
     .catch((err) => {
   return err})

第二种通过Qs模块。安装qs模块:cnpm install qs --save
在这里插入图片描述
在main.js 中添加:

import qs from 'qs';
Vue.prototype.$qs = qs

使用qs:

this.$axios.post('/api/xxxx',
   this.$qs.stringify({
   
      username:this.username,
      password:this.password
   }),
)

5.解决跨域问题

例如直接请求 https://www.baidu.com 会被跨域拦截后报错。
在这里插入图片描述
关于跨域问题请自行了解,如下采用代理的方式解决跨域问题。

代理可以解决的原因:因为客户端请求服务端的数据是属于跨域的,而服务器和服务器之间可以相互请求数据,是没有跨域的概念的(如果服务器没有设置禁止跨域的权限问题),也就是说,我们可以配置一个代理的服务器代替客户端去请求目的服务器中的数据,然后代理服务器把请求到的数据再返回到我们的客户端,这样我们就可以实现了客户端的跨域请求。

5.1 开发环境下:
在我们本地IDE中作开发时代理的方式是,利用Vue-cli提供的代理功能,它(http-server-middleware)依赖于node环境,所以直接配置即可:

首先将前文axios/index.js中配置的baseURL的值改为'/apis'。这样每次发送请求都会带一个/apis的前缀。

···
var instance = axios.create({
   
  headers:{
   
    post:{
   'Content-Type':'application/x-www-form-urlencoded;charset=utf-8'}	//post请求头
  },
  timeout: 10000,	//请求超时时间
  baseURL: '/apis',   //改为 /apis
  withCredentials: true //允许请求携带cookie信息
});
···

修改config文件夹下的index.js文件,在proxyTable中加上如下代码:

proxyTable: {
   
      '/apis':{
   
        target: "https://www.baidu.com",
        changeOrigin:true,
        pathRewrite:{
   
          '^/apis':''
        }
      }
    },

修改刚刚的axios请求,把url修改如下:

this.$axios.get("/")
.then(res=>{
   
	console.log(res)
})
.catch(err=>{
   
	console.log(err)
})

重启服务后,此时已经能够请求到数据了:
在这里插入图片描述
代理的原理:我们将baseURL设置为/apis,这样我们所有的请求的开头都会是这个基础url,如我们代理后请求的地址为/,但实际发送的请求是/apis/,然后又因为我们在index.js中配置了代理,proxyTable中拦截了我们设置的那个公用url开头的字符/apis,并把 /apis 及其前面的所有替换成了target 中的内容,于是,看似我们请求的是/,实际经过axios配合和代理后,请求地址变为了https://www.baidu.com/,并且这个请求的发出者是代理服务器。(代理服务器收到的客户端的请求是/apis/,经过上述的处理后变为最终正确的请求地址)

另外,升级到 Vue3 后,会发现 Vue2 中存放配置的 config 文件夹没有了。可以在 package.json 文件的同级目录下创建 vue.config.js 文件。给出该文件的基础配置:

module.exports = {
   
    outputDir: 'dist',   //build输出目录
    assetsDir: 'assets', //静态资源目录(js, css, img)
    lintOnSave: false, //是否开启eslint
    devServer: {
   
        open: true, //是否自动弹出浏览器页面
        host: "localhost", 
        port: '8081', 
        https: false,   //是否使用https协议
        hotOnly: false, //是否开启热更新
        proxy: null,
    }
}

接下来Vue3 解决跨域,除了添加代理配置的位置 和 Vue2 不同,其他的一致。

修改vue.config.jsdevServer 子节点内容,添加一个 proxy

devServer: {
   
    open: true, //是否自动弹出浏览器页面
    host: "localhost", 
    port: '8081',
    https: false,
    hotOnly: false, 
    proxy: {
   
        '/apis': {
   
            target: 'https://www.baidu.com', //API服务器的地址
            changeOrigin: true,
            pathRewrite: {
   
                '^/apis': ''
            }
        }
    },
}

5.2 生产环境下:
最开始由于不熟悉nginx服务器,所以项目打包后是直接部署到的tomcat,但是之前提到过,我们之前开发环境配置的那个代理依赖于node环境,到了tomcat后之前的配置全都成了无用的字符串,自然代理就失效了,后来了解到nginx是专门的web容器,并且可以实现反向代理,安装步骤略,配置代理方法如下:

在安装目录下的conf/nginx.conf配置文件中部署配置下添加:

···
		#项目配置的路径
		location / {
   
            root   html/pahms;
            index  index.html index.htm;
        }
		#代理配置
		location /apis {
   
			proxy_pass   http://www.korb1n.cn/pahms;
			#解决反向代理cookie和session丢失的问题
			proxy_cookie_path  /pahms /apis;	
       }
···

重启刷新nginx服务就可以了。

在配置中可以看到代理配置中还有一行注释的是解决丢失cookie和session的问题,可以参考我的另一篇踩坑记录:解决nginx proxy_pass反向代理cookie,session丢失的问题

补充:当然跨域问题也可以从后端解决,请求的服务器如果设置了允许跨域请求,也就不会被拦截了,参考我的另一篇博文:Springboot解决跨域问题Springboot加了拦截器后出现的跨域问题解析

本文来源MrKorbin,由架构君转载发布,观点不代表Java架构师必看的立场,转载请标明来源出处:https://javajgs.com/archives/25309

发表评论