1.1 axios 基本用法
安裝: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

<!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>

<!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>

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上傳文件

<!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>

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.csdn.net/qq_40128367/article/details/82735310
1、初始化vue項目
# vue init webpack deaxios # npm install axios -S # cnpm install vuex -S # cnpm install vant -S # cnpm install nprogress -S
2、封裝axios(創建 src/api 文件夾)

export default { // api請求地址 API_URL: 'http://127.0.0.1:8000/' }

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) }) }); }

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); } } ); export default instance

import * as api from './api' export default api

import Vue from 'vue' import Vuex from 'vuex' import * as api from '../api/api' Vue.use(Vuex); export default new Vuex.Store({ modules:{ api } });

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發送請求

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);

<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>
4、如果需要上傳圖片或文件 src\api\ajax.js 中傳入的 params參數不可使用Qs序列化

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) { var isFormData = Object.prototype.toString.call(params) === '[object FormData]' var data = ''; // 如果是上傳文件傳入的 params是一個 FormData對象,不要用Qs序列化 if(isFormData){ data = params }else { data = Qs.stringify( //3、可選函數、序列化`data` params, //4、提交數據 { indices: false } // indices: false ) } return new Promise((resolve, reject) => { instance({ url: url, //1、請求地址 method: 'post', // 2、請求方法 data: data, headers: { 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8' }, }) // 2、回調函數 .then(res => { resolve(res.data); }) // 3、捕獲異常 .catch(err => { reject(err.data) }) }); }

<template> <div id="itany"> <input type="file" name="fileUpload" id="fileUp" @change="change($event)" ref="inputFile" > <button @click="sendPost">POST方式發送axios請求</button> </div> </template> <script> import { createGoods } from '../../api/api' export default { data() { return {} }, methods: { sendPost(){ // 1、發送post請求 var data = new FormData(); data.append("fafafa",this.file) // 圖片對象 data.append("username","zhangsan") // 其他key-value值 createGoods(data) // 2、回調函數 .then(resp => { console.log(resp); }) // 3、捕獲異常 .catch(err => { console.log('請求失敗:'+err.status+','+err.statusText); }); }, change:function(event){ this.file = event.target.files[0] }, } } </script> <style scoped> </style>

def data(request): if request.method == 'GET': token_id = request.META.get('HTTP_AUTHORIZATION') # header中的tokenid data = {'id':1,'name': 'zhangsan'} return HttpResponse(json.dumps(data)) elif request.method == 'POST': username = request.POST.get('username') fafafa = request.FILES.get('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.3 vue配置前端跨域
參考博客:https://www.cnblogs.com/qqing/p/8980199.html
1、初始化vue項目
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
//加入以下
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 中設置以下代碼
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、修改src\App.vue文件
<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>
7、說明
1. vue前端結局跨域主要思想是代理功能,比如:
vue項目:http://localhost:8080/
后端項目:http://127.0.0.1:8000/
2. 在瀏覽器端訪問 http://localhost:8080/api/index/ 路徑時,vue會匹配到以 /api/ 開頭的請求
3. 此時 vue會使用代理功能 自動轉發到 http://127.0.0.1:8000/index/ 此時就是同一個域,就不會觸發跨域問題
11111111111111