Axios

李莲花發表於2024-08-17

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 &gt;= 200 &amp;&amp; status &lt; 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請求

  1. 表單提交
    若:<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);
            }
        })
    }
}

相關文章