axios封装 1.1 axios 基本用法 1.2 封装axios发送请求 & 添加拦截器 3、使用封装的axios发送请求 1.3 vue配置前端跨域
安装:npm install axios -S # 也可直接下载axios.min.js文件
1、axios借助Qs对提交数据进行序列化
axios参考博客:https://www.jianshu.com/p/68d81da4e1ad
https://www.cnblogs.com/yiyi17/p/9409249.html
axios官网:https://www.npmjs.com/package/axios
get:axios发送请求
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
|
<!DOCTYPE html> <html lang= "en" >
<head> <meta charset= "UTF-8" >
<title>发送AJAX请求</title>
</head> <body> <div id= "itany" >
<button @click= "sendGet" >GET方式发送AJAX请求</button>
</div> <script src= "js/vue.js" ></script>
<script src= "js/axios.min.js" ></script>
<script src= "js/qs.js" ></script>
<script> window.onload=function(){
new Vue({
el: '#itany' ,
data:{
uid: ''
},
methods:{
sendGet(){
// 1、发送get请求
axios({
url: 'http://127.0.0.1:8000/data/' , //1、请求地址
method: 'get' , //2、请求方法
params : {ids: [1,2,3],type: 'admin' }, //3、get请求参数
paramsSerializer: params => { //4、可选函数、序列化`params`
return Qs.stringify( params , { indices: false })
},
responseType: 'json' , //5、返回默认格式json
headers: { 'authorization' : 'xxxtokenidxxxxx' }, //6、认证token
})
// 2、回调函数
.then(resp => {
console.log(resp.data);
})
// 3、捕获异常
. catch (err => {
console.log( '请求失败:' +err.status+ ',' +err.statusText);
});
}
}
});
}
</script> </body> </html> |
post:axios发送请求
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
<!DOCTYPE html> <html lang= "en" >
<head> <meta charset= "UTF-8" >
<title>发送AJAX请求</title>
</head> <body> <div id= "itany" >
<button @click= "sendPost" >POST方式发送AJAX请求</button>
</div> <script src= "js/vue.js" ></script>
<script src= "js/axios.min.js" ></script>
<script src= "js/qs.js" ></script>
<script> window.onload=function(){
new Vue({
el: '#itany' ,
data:{
uid: ''
},
methods:{
sendPost(){
// 1、发送post请求
axios({
url: 'http://127.0.0.1:8000/data/' , //1、请求地址
method: 'post' , // 2、请求方法
data: Qs.stringify( //3、可选函数、序列化`data`
{ids: [1,2,3],type: 'admin' }, //4、提交数据
{ indices: false } // indices: false
),
responseType: 'json' , //5、返回默认格式json
headers: { 'authorization' : 'xxxtokenidxxxxx' }, //6、身份验证token
})
// 2、回调函数
.then(resp => {
console.log(resp.data);
})
// 3、捕获异常
. catch (err => {
console.log( '请求失败:' +err.status+ ',' +err.statusText);
});
}
}
});
}
</script> </body> </html> |
views.py后端测试接口
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
def data(request): if request.method == 'GET' :
token_id = request.META. get ( 'HTTP_AUTHORIZATION' ) # header中的tokenid
print(request.GET.getlist( 'ids' )) # 获取 get 请求中列表
data = {
'id' :1,
'name' : 'zhangsan'
}
return HttpResponse(json.dumps(data))
elif request.method == 'POST' :
token_id = request.META. get ( 'HTTP_AUTHORIZATION' ) # header中的tokenid
print(request.POST.getlist( 'ids' )) # 获取post请求中的列表
data = {
'id' :1,
'name' : 'zhangsan' ,
'method' : 'POST'
}
return HttpResponse(json.dumps(data))
|
#1、qs用途: 在 axios中,利用QS包装data数据 #2、安 装: npm install qs -S #3、常见用法: ''' import Qs from 'qs'; Qs.stringify(data); Qs.parse(data)
2、axios上传文件
1)test.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
|
<!DOCTYPE html> <html lang= "en" >
<head> <meta charset= "UTF-8" >
<title>发送axios请求</title>
</head> <body> <div id= "itany" >
<input type= "file" name= "fileUpload" id= "fileUp" @change= "change($event)" ref = "inputFile" >
<button @click= "sendPost" >POST方式发送axios请求</button>
</div> <script src= "js/vue.js" ></script>
<script src= "js/axios.min.js" ></script>
<script src= "js/qs.js" ></script>
<script> window.onload=function(){
new Vue({
el: '#itany' ,
data:{
uid: ''
},
methods:{
sendPost(){
// 1、发送post请求
var data = new FormData();
data.append( "fafafa" , this .file) // 图片对象
data.append( "username" , "zhangsan" ) // 其他key-value值
axios({
url: 'http://127.0.0.1:8000/data/' , //1、请求地址
method: 'post' , //2、请求方法
data: data, //3、提交的数据
responseType: 'json' , //4、返回默认格式json
headers: { 'authorization' : 'xxxtokenidxxxxx' }, //5、身份验证token
})
// 2、回调函数
.then(resp => {
console.log(resp.data);
})
// 3、捕获异常
. catch (err => {
console.log( '请求失败:' +err.status+ ',' +err.statusText);
});
},
change:function( event ){
this .file = event .target.files[0]
},
},
});
}
</script> </body> </html> |
2)views.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
def data(request): if request.method == 'GET' :
data = {
'id' :1,
'name' : 'zhangsan'
}
return HttpResponse(json.dumps(data))
elif request.method == 'POST' :
username = request.POST. get ( 'username' )
fafafa = request.FILES. get ( 'fafafa' )
print(username, fafafa)
with open(fafafa.name, 'wb' ) as f:
for item in fafafa.chunks():
f.write(item)
ret = { 'code' : True, 'data' : request.POST. get ( 'username' )}
data = {
'id' :1,
'name' : 'zhangsan' ,
'method' : 'POST'
}
return HttpResponse(json.dumps(data))
|
1.2 封装axios发送请求 & 添加拦截器
参考:https://blog.****.net/qq_40128367/article/details/82735310
1、初始化vue项目
1
2
3
4
5
|
# vue init webpack deaxios # npm install axios -S # cnpm install vuex -S # cnpm install vant -S # cnpm install nprogress -S |
2、封装axios(创建 src/api 文件夹)
configurls.js 配置全局url变量
export default {
// api请求地址
API_URL: 'http://127.0.0.1:8000/'
}
srcapiajax.js 封装axios请求
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
import Qs from 'qs'
import instance from './axiosinstance' // 导入自定义 axios 实例
// import instance from 'axios' // 也可以直接使用原生 axios 实例,但无法添加拦截器 /* 1. 发送GET请求 */ export function get (url, params ){
return new Promise((resolve, reject) =>{
// 1、发送get请求
instance({
url: url, //1、请求地址
method: 'get' , //2、请求方法
params : params , //3、get请求参数
headers: {
'Content-Type' : 'application/json'
},
paramsSerializer: params => { //4、可选函数、序列化`params`
return Qs.stringify( params , { indices: false })
},
})
// 2、回调函数
.then(res => {
resolve(res.data);
})
// 3、捕获异常
. catch (err => {
reject(err.data)
});
});
} /* 2. 发送POST请求 */ export function post(url, params ) {
return new Promise((resolve, reject) => {
instance({
url: url, //1、请求地址
method: 'post' , // 2、请求方法
data: Qs.stringify( //3、可选函数、序列化`data`
params , //4、提交数据
{ indices: false } // indices: false
),
headers: {
'Content-Type' : 'application/x-www-form-urlencoded;charset=UTF-8'
},
})
// 2、回调函数
.then(res => {
resolve(res.data);
})
// 3、捕获异常
. catch (err => {
reject(err.data)
})
});
} |
srcapiaxiostance.js 自定义 axios 实例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
|
import Axios from 'axios'
import { Toast } from 'vant' ;
import URLS from '../../config/urls'
//1、使用自定义配置新建一个 axios 实例 const instance = Axios.create({
baseURL: URLS.API_URL,
responseType: 'json' ,
}); //2、添加请求拦截器:每次发送请求就会调用此拦截器,添加认证token instance.interceptors.request.use( config => {
//发送请求前添加认证token,
config.headers.Authorization = sessionStorage.getItem( 'token' )
return config
},
err => {
return Promise.reject(err)
});
// 3、响应拦截器 instance.interceptors.response.use( response => {
if (response.status === 200) {
return Promise.resolve(response);
} else {
return Promise.reject(response);
}
},
// 服务器状态码不是200的情况
error => {
if (error.response.status) {
switch (error.response.status) {
// 401: 未登录
// 未登录则跳转登录页面,并携带当前页面的路径
// 在登录成功后返回当前页面,这一步需要在登录页操作。
case 401:
router.replace({
path: '/login' ,
query: { redirect: router.currentRoute.fullPath }
});
break ;
// 403 token过期
// 登录过期对用户进行提示
// 清除本地token和清空vuex中token对象
// 跳转登录页面
case 403:
Toast({
message: '登录过期,请重新登录' ,
duration: 1000,
forbidClick: true
});
// 清除token
localStorage.removeItem( 'token' );
store.commit( 'loginSuccess' , null );
// 跳转登录页面,并将要浏览的页面fullPath传过去,登录成功后跳转需要访问的页面
setTimeout(() => {
router.replace({
path: '/login' ,
query: {
redirect: router.currentRoute.fullPath
}
});
}, 1000);
break ;
// 404请求不存在
case 404:
Toast({
message: '网络请求不存在' ,
duration: 1500,
forbidClick: true
});
break ;
// 其他错误,直接抛出错误提示
default :
Toast({
message: error.response.data.message,
duration: 1500,
forbidClick: true
});
}
return Promise.reject(error.response);
}
}
); |
srcapiindex.is 导出api模块
1
2
3
|
import * as api from './api'
export default api
|
srcstoreindex.js 全局导出路由方法变量
1
2
3
4
5
6
7
8
9
10
11
|
import Vue from 'vue'
import Vuex from 'vuex'
import * as api from '../api/api'
Vue.use(Vuex); export default new Vuex.Store({
modules:{
api
}
}); |
main.js 使用钩子函数进行路由方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
import Vue from 'vue'
import App from './App'
import router from './router'
import NProgress from 'nprogress'
import store from './store/index'
Vue.config.productionTip = false
/* 定义:路由钩子主要是给使用者在路由发生变化时进行一些特殊的处理而定义的函数 */ router.afterEach(transition => { setTimeout(() => {
NProgress.done()
})
}) window.APP_INFO = process.env.APP_INFO router.beforeEach((to, from , next) => {
/*
* to: router即将进入的路由对象
* from: 当前导航即将离开的路由
* next: 进行管道中的一个钩子,如果执行完了,则导航的状态就是 confirmed (确认的);否则为false,终止导航。
* */
NProgress.start()
// 使用假数据模拟张三已经登录
localStorage.setItem( 'user' , JSON.stringify({ 'username' : 'zhangsan' }) )
if (to.path === '/login' ) {
localStorage.removeItem( 'user' )
}
let user = JSON.parse(localStorage.getItem( 'user' ))
if (!user && to.path !== '/login' ) { // 如果用户没有登录,且访问url不是 '/login' 调整到登录页
next({ path: '/login' })
} else {
next()
}
}) /* 拦截器介绍位置 */ /* eslint-disable no-new */ new Vue({
el: '#app' ,
router,
store,
components: { App },
template: '<App/>'
}) |
3、使用封装的axios发送请求
srcapiapi.js 定义请求路由方法
import URLS from '../../config/urls' import { get, post } from './ajax' let base = URLS.API_URL // 用户相关 export const postLogin = p => post(`${base}/login/`, p); export const getLogin = p => get(`${base}/login/`, p);
App.vue 导入路由请求方法测试请求数据
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
<template> <div id= "app" >
<router-view/>
</div>
</template> <script> import { postLogin,getLogin } from './api/api' // 导入路由请求方法
export default {
name: 'App' ,
created () {
this .testGet();
this .testPost();
},
methods: {
// 获取数据
testPost() {
// 调用api接口,并且提供了两个参数
postLogin({
type: 0,
sort: 1,
lst:[1,2,3,4,5]
}).then(res => {
// 获取数据成功后的其他操作
console.log(res,1111111)
}). catch (
)
},
testGet() {
// 调用api接口,并且提供了两个参数
getLogin({
type: 0,
sort: 1,
lst:[1,2,3,4,5]
}).then(res => {
// 获取数据成功后的其他操作
console.log(res,22222222222222)
}). catch (
)
},
}
}
</script> |
1.3 vue配置前端跨域
参考博客:https://www.cnblogs.com/qqing/p/8980199.html
1、初始化vue项目
1
2
3
4
|
vue init webpack my-project # 初始化项目 cd my-project # 进入项目路径 cnpm install # 安装依赖 cnpm install axios -S # 安装axios |
2、在 src/main.js 中如下声明使用
import axios from 'axios'; Vue.prototype.$axios=axios;
3、在 config/index.js 中的 的dev 添加以下代码,设置一下proxyTable
1
2
3
4
5
6
7
8
9
10
11
12
|
//加入以下 proxyTable:{
'/api' : {
target : 'http://127.0.0.1:8000' , //设置你调用的接口域名和端口号.别忘了加http
changeOrigin : true , //允许跨域
pathRewrite : {
'^/api' : ''
// ''这里理解成用‘/api’代替target里面的地址,后面组件中我们掉接口时直接用api代替。
// 比如我要调用'http://127.0.0.1:8000/index/',直接写‘/api/index/’即可
}
}
},
|
4、在 config/dev.env.js 中设置以下代码
1
2
3
4
|
module.exports = merge(prodEnv, { NODE_ENV: '"development"' , //开发环境
API_HOST: "/api/"
}) |
5、在 config/prod.env.js 中设置以下代码
module.exports = { NODE_ENV: '"production"',//生产环境 API_HOST:'"127.0.0.1:8000"' }
6、修改srcApp.vue文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
<template> <div id= "app" >
<button @click= "testAxios()" >测试axios</button>
</div>
</template> <script> import axios from 'axios' ;
export default {
data () {
return {
}
},
methods:{
testAxios () {
this .$axios. get ( '/api/index/' )
.then((response) => {
console.log(response.data)
})
}
}
}
</script> |