在写个人笔记项目时,需要给后端接口发送请求来完成登录,注册,注销等等的操作。
这时我要用Ajax进行前后端联调,在Vue项目里可以使用Axios,而不需要使用fetch或者XHR。
Axios 是一个基于 promise 的网络请求库,可以让代码在浏览器和node.js中都可运行。
开始
npm install axios
然后在src目录下创建一个helper目录,专门存放被多次利用的组件。在其中创建request.js,来存放我们的请求代码。
首先引入Axios
import axios from 'axios'
Axios配置有全局默认值
axios.defaults.baseURL = 'https://api.example.com';
axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
这里的baseURL我们换成接口的域名,这个设置了很有好处,可以避免我们每次切换请求都要输入全部的域名。
而axios.defaults.withCredentials = true是表示跨域请求时是否需要使用凭证。我的项目和接口并不在同一URL下,所以是跨域,需要服务端要设置Access-Control-Allow-Origin。
withCredentials是XMLHttpRequest的一个属性,表示跨域请求是否提供凭据信息(cookie、HTTP认证及客户端SSL证明等)
开启withCredentials后,能拿到你的session_id了,不然每次你的session_id都在变化。
import axios from 'axios'
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded'
axios.defaults.baseURL = 'http://note-server.hunger-valley.com'
axios.defaults.withCredentials = true
export default function request (url, type = 'GET', data = {}) {
return new Promise((resolve, reject) => {
let options = {
url,
method: type,
validateStatus (status) {
return ((status >= 200 && status < 300) || status === 400)
}
}
if (type.toLowerCase() === 'get') { //如果method为GET
options.params = data //在请求url里加上data
} else { //若不是GET
options.data = data //在请求体body里加上data
}
axios(options).then(res => { //用axios处理options对象
if (res.status === 200) { //若状态码表示成功
resolve(res.data) //resolved
} else {
console.error(res.data)
reject(res.data)
}
}).catch(err => {
console.error('网路异常')
reject(err, {msg: '网路异常'})
})
})
}
这里,我们暴露一个request函数给外部使调用。传入三个参数,url,type和data。
新建一个Promise对象,再创建一个options对象,这个options对象就是我们要传递的请求的相关信息。
url是具体请求的接口。
type是method。
data是需要传递的数据。
validateStatus 定义了对于给定的 HTTP状态码是 resolve 还是 reject。如果验证为true,那么将会执行resolved,否则执行rejected。
外部调用
import request from '../helpers/request'
request('/auth/login', 'POST', {
username: this.login.username,
password: this.login.password
}).then(data => console.log(data))
封装几个API
新建一个auth.js
import request from '../helpers/request'
const URL = {
REGISTER: '/auth/register',
LOGIN: '/auth/login',
LOGOUT: '/auth/logout',
GET_INFO: '/auth'
}
export default {
register ({username, password}) {
return request(URL.REGISTER, 'POST', {username, password})
},
login ({username, password}) {
return request(URL.LOGIN, 'POST', {username, password})
},
logout () {
return request(URL.LOGOUT)
},
getInfo () {
return request(URL.GET_INFO)
}
}
清晰明了,对四个接口进行了一个封装。
外部调用
import auth from '../api/auth'
auth.login({
username: this.login.username,
password: this.login.password
}).then(data => console.log(data))
简明了很多。
可能出现的BUG
但是在封装auth之后会遇到chrome曾更新政策导致的跨域bug,请参考这篇文章:juejin.cn/post/714132…