1.Axios
1.1 非同步請求發展史
1.1.1 傳統的Ajax
傳統的Ajax請求是基於XMLHttpRequest(XHR)物件。可以直接使用。但 是使用起來配置較為麻煩,實際開發中使用非常少,在MVC時代通常使用的 是JQuery-Ajax。相對於傳統的Ajax現在使用更多的是Fetch請求。
1.1.2 JQuery-Ajax
JQuery-Ajax在前端JQuery時,因為JQuery的強大相容性在專案開發中 $Ajax使用非常廣泛,需要引入JQuery庫,其底層原理也是對傳統的Ajax,XHR物件進行封裝。但是在前端框架MVVC時代,例如使用vue搭建專案, 如果再繼續使用$Ajax就還需再單獨引入JQuery重量級1w+程式碼量的庫是 得不償失的。所以針對於框架的網路請求應運而生。
1.1.3 Axios
在Vue1.0時代,官方推出了Vue-resource,其體積相對於JQuery小得多,但是在Vue2.0時代官方宣佈不再更新,那麼繼續使用Vue-resource就會存在版本無法匹配問題。因此在Vue2.0時代開始,官方推薦使用axios作為新一代的Ajax庫。axios其優點:在瀏覽器中傳送XMLHttpRequest請求、在node中傳送http請求、支援Promise API、攔截請求和相應、轉換請求和響應資料等
1.2 安裝方法
使用 cdn:
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="https://cdn.staticfile.org/axios/0.18.0/axios.min.js"></script>
使用 npm:npm install axios
1.3 axios的格式
axios(config)
axios({
key:value,
...
key:value
}).then(function(res){
console.log(res);
}).catch(err=>{
console.log(err);
})
1.3.1請求配置項:config的詳細配置引數
下面是建立請求時可用的配置選項,注意只有 url 是必需的。
如果沒有指定 method,請求將預設使用 get 方法
// `url` 是用於請求的伺服器 URL
url: "/user",
// `method` 是建立請求時使用的方法
method: "get", // 預設是 get
// `headers` 是即將被髮送的自定義請求頭
headers: {"X-Requested-With": "XMLHttpRequest"},
// `params` 是即將與請求一起傳送的 URL 引數
// 必須是一個無格式物件(plain object)或 URLSearchParams 物件
params: {
ID: 12345
},
// 在沒有設定 `transformRequest` 時,必須是以下型別之一:
// - string, plain object, ArrayBuffer, ArrayBufferView, URLSearchParams
// - 瀏覽器專屬:FormData, File, Blob
// -data和params的區別:
//params是用來攜帶請求引數的,它以key-value的形式放在URL後面,是一個物件。
//data是用來攜帶請求資料的,它以key-value的形式放在請求體中,是一個物件。
//axios預設使用JSON格式傳送請求,所以如果你使用data傳送請求,請確保伺服器能夠處理JSON格式的資料
data: {
firstName: "Fred"
},
// `baseURL` 將自動加在 `url` 前面,除非 `url` 是一個絕對 URL。
// 它可以透過設定一個 `baseURL` 便於為 axios 例項的方法傳遞相對 URL
baseURL: "https://some-domain.com/api/",
// `transformRequest` 允許在向伺服器傳送前,修改請求資料
// 只能用在 "PUT", "POST" 和 "PATCH" 這幾個請求方法
transformRequest: [function (data) {
// 對 data 進行任意轉換處理
return data;
}],
// `transformResponse` 在傳遞給 then/catch 前,允許修改響應資料
transformResponse: [function (data) {
// 對 data 進行任意轉換處理
return data;
}],
// `paramsSerializer` 是一個負責 `params` 序列化的函式
// (e.g. https://www.npmjs.com/package/qs, https://api.jquery.com/jquery.param/)
paramsSerializer: function(params) {
return Qs.stringify(params, {arrayFormat: "brackets"})
},
// `timeout` 指定請求超時的毫秒數(0 表示無超時時間)
// 如果請求花費了超過 `timeout` 的時間,請求將被中斷
timeout: 1000,
// `withCredentials` 表示跨域請求時是否需要使用憑證
withCredentials: false, // 預設的
// `adapter` 允許自定義處理請求,以使測試更輕鬆
// 返回一個 promise 並應用一個有效的響應 (查閱 [response docs](#response-api)).
adapter: function (config) {
},
// `auth` 表示應該使用 HTTP 基礎驗證,並提供憑據
// 這將設定一個 `Authorization` 頭,覆寫掉現有的任意使用 `headers` 設定的自定義 `Authorization`頭
auth: {
username: "janedoe",
password: "s00pers3cret"
},
// `responseType` 表示伺服器響應的資料型別,可以是 "arraybuffer", "blob", "document", "json", "text", "stream"
responseType: "json", // 預設的
// `xsrfCookieName` 是用作 xsrf token 的值的cookie的名稱
xsrfCookieName: "XSRF-TOKEN", // default
// `xsrfHeaderName` 是承載 xsrf token 的值的 HTTP 頭的名稱
xsrfHeaderName: "X-XSRF-TOKEN", // 預設的
// `onUploadProgress` 允許為上傳處理進度事件
onUploadProgress: function (progressEvent) {
// 對原生進度事件的處理
},
// `onDownloadProgress` 允許為下載處理進度事件
onDownloadProgress: function (progressEvent) {
// 對原生進度事件的處理
},
// `maxContentLength` 定義允許的響應內容的最大尺寸
maxContentLength: 2000,
// `validateStatus` 定義對於給定的HTTP 響應狀態碼是 resolve 或 reject promise 。如果 `validateStatus` 返回 `true` (或者設定為 `null` 或 `undefined`),promise 將被 resolve; 否則,promise 將被 rejecte
validateStatus: function (status) {
return status >= 200 && status < 300; // 預設的
},
// `maxRedirects` 定義在 node.js 中 follow 的最大重定向數目
// 如果設定為0,將不會 follow 任何重定向
maxRedirects: 5, // 預設的
// `httpAgent` 和 `httpsAgent` 分別在 node.js 中用於定義在執行 http 和 https 時使用的自定義代理。允許像這樣配置選項:
// `keepAlive` 預設沒有啟用
httpAgent: new http.Agent({ keepAlive: true }),
httpsAgent: new https.Agent({ keepAlive: true }),
// "proxy" 定義代理伺服器的主機名稱和埠
// `auth` 表示 HTTP 基礎驗證應當用於連線代理,並提供憑據
// 這將會設定一個 `Proxy-Authorization` 頭,覆寫掉已有的透過使用 `header` 設定的自定義 `Proxy-Authorization` 頭。
proxy: {
host: "127.0.0.1:5000",
port: 9000,
auth: {
username: "mikeymike",
password: "rapunz3l"
}
},
// `cancelToken` 指定用於取消請求的 cancel token
// (檢視後面的 Cancellation 這節瞭解更多)
cancelToken: new CancelToken(function (cancel) {
})
1.3.2響應結構:then中response資訊
.then(function(response){
console.log(response);
// `data` 由伺服器提供的響應
console.log(response.data);
// `status` HTTP 狀態碼
console.log(response.status);
// `statusText` 來自伺服器響應的 HTTP 狀態資訊
console.log(response.statusText);
// `headers` 伺服器響應的頭
console.log(response.headers);
// `config` 是為請求提供的配置資訊
console.log(response.config);
})
1.3.3錯誤處理
.catch(function (error) {
if (error.response) {
// 請求已發出,但伺服器響應的狀態碼不在 2xx 範圍內
console.log(error.response.data);
console.log(error.response.status);
console.log(error.response.headers);
} else {
// Something happened in setting up the request that triggered an Error
console.log('Error', error.message);
}
console.log(error.config);
});
1.4 簡化寫法
格式:
• axios(config) ====== axios.request(config)
• axios.get(url[, config])
• axios.delete(url[, config])
• axios.head(url[, config])
• axios.post(url[, data[, config]])
• axios.put(url[, data[, config]])
• axios.patch(url[, data[, config]])
案例展示:
1、axios(config)請求方式:
axios接收一個物件,在物件中使用鍵值對方式寫入配置資訊,get請求下,預設method可以不寫
2、axios.request(config)請求方式: 與axios(config)寫法一致
3、axios.get(url[, config])請求方式 :限定method為get請求
- 表單提交
若:<input type="text"/>
,則v-model收集的是value值,使用者輸入的就是value值。
若:<input type="radio"/>
,則v-model收集的是value值,且要給標籤配置value值。
若:<input type="checkbox"/>
1.沒有配置input的value屬性,那麼收集的就是checked(勾選 or 未勾選,是布林值)
2.配置input的value屬性:
(1)v-model的初始值是非陣列,那麼收集的就是checked(勾選 or 未勾選,是布林值)
(2)v-model的初始值是陣列,那麼收集的的就是value組成的陣列
備註:v-model的三個修飾符:
lazy:失去焦點再收集資料
number:輸入字串轉為有效的數字
trim:輸入首尾空格過濾
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js/vue.js"></script>
<script src="./js/axios.min.js"></script>
</head>
<body>
<div id="app">
<form>
賬號:<input type="text" v-model.trim="user.userCode"><br/><br/>
密碼:<input type="password" v-model="user.userPwd"><br/><br/>
性別:<input type="radio" v-model="user.userSex" value="男">男
<input type="radio" v-model="user.userSex" value="女">女<br/><br/>
愛好:<input type="checkbox" v-model="user.userHobby" value="看書">看書
<input type="checkbox" v-model="user.userHobby" value="睡覺">睡覺
<input type="checkbox" v-model="user.userHobby" value="游泳">游泳
地址:<select v-model="user.address">
<option value="shanghai">上海</option>
<option value="北京">北京</option>
<option value="天津">天津</option>
</select>
<br/><br/>
其他資訊:
<textarea v-model.lazy="user.other"></textarea> <br/><br/>
<input type="checkbox" v-model="user.userAgree">閱讀並接受<a href="http://www.atguigu.com">《使用者協議》</a>
<button @click="submitUser($event)">提交</button>
</form>
</div>
<script>
new Vue({
el:"#app",
data(){
return {
user:{
userCode:"",
userPwd:"",
userSex:"",
address:"",
other:"",
userAgree:"",
//userHobby:[]陣列不能以引數的形式傳遞
}
}
},
methods:{
submitUser(event){
event.preventDefault();//阻止預設的點選事件執行
console.log(this.user)
axios({
url:"getVueForm.action",
method:"POST",
params:this.user
}).then((result)=>{
//注意表單提交事件會導致頁面重新整理
console.log(result.data.messageStr)
alert(result.data.messageStr)
})
}
}
});
</script>
</body>
</html>
2.檔案上傳
非同步檔案上傳檔案依然需要Mulitpart/from-data
2.1用js的formData物件上傳
頁面:
<input class="file" name="file" type="file" @change="update"/>
Axios處理
methods: {
update(e){
let file = e.target.files[0];
let param = new FormData(); //建立form物件
param.append('file',file);//透過append向form物件新增資料
console.log(param.get('file')); //FormData私有類物件,訪問不到,可以透過get判斷值是否傳進去
let config = {
headers:{'Content-Type':'multipart/form-data'} //這裡是重點,需要和後臺溝通好請求頭,Content-Type不一定是這個值
}; //新增請求頭
axios.post('upload',param,config)
.then(response=>{
console.log(response.data);
})
}
}
3.form表單的檔案上傳
頁面
<form>
<input type="text" value="" v-model="name" placeholder="請輸入使用者名稱">
<input type="text" value="" v-model="age" placeholder="請輸入年齡">
<input type="file" @change="getFile($event)">
<button @click="submitForm($event)">提交</button>
</form>
處理:
data: {
name: '',
age: '',
file: ''
},
methods: {
getFile(event) {
this.file = event.target.files[0];
console.log(this.file);
},
submitForm(event) {
event.preventDefault();//阻止預設的點選事件執行
let formData = new FormData();
formData.append('name', this.name);
formData.append('age', this.age);
formData.append('file', this.file);
let config = {
headers: {
'Content-Type': 'multipart/form-data'
}
}
axios.post('upload', formData, config).then(function (response) {
if (response.status === 200) {
console.log(response.data);
}
})
}
}