第三十節(jié):Vue請(qǐng)求:Axios請(qǐng)求


1. 網(wǎng)絡(luò)請(qǐng)求的方式

發(fā)送網(wǎng)絡(luò)請(qǐng)求的方式有很多種,到目前為止,我們已經(jīng)學(xué)過(guò)了原生ajax,jquery中的ajax,等諸多網(wǎng)絡(luò)請(qǐng)求的方式,那么在未來(lái)我們vue的項(xiàng)目中我們?cè)撊绾尉駬衲?/p>

先來(lái)分析一下不同的ajax請(qǐng)求,了解使用與否的理由

1.1 原生Ajax

原生ajax是基于XMLHttpRequest(XHR)封裝的.

我們都知道原生的ajax不但有兼容問(wèn)題,而且配置很調(diào)用都非呈钊校混亂, 這也是我們不使用的理由


1.2 jquery中的ajax

這個(gè)之前也提到過(guò)這類(lèi)問(wèn)題, jquery的ajax相對(duì)于原生的ajax來(lái)說(shuō)非常好用, 但是jquery的ajax是嵌入在真?zhèn)€jquery中的,因此如果我們要使用jquery的ajax,就需要引入整體的jquery但是在咱們Vue項(xiàng)目的整個(gè)開(kāi)發(fā)過(guò)程中都不需要在使用jquery,只為了用一個(gè)ajax,引入整體的jquery, 得不償失.因此在vue中也不選用jquery 的ajax


1.3 Vue 在1.X版本是推出的Vue-resource插件

Vue-resource相較于jquery要輕量很多, 但是Vue從2.X以后就表示不再更新維護(hù)了, 如果使用它處理ajax請(qǐng)求,未來(lái)代碼的維護(hù)上,是有很大的安全隱患的, 包括現(xiàn)在vue官網(wǎng)也不推薦你是用Vue-resource處理ajax

Vue官網(wǎng)推薦使用axios處理ajax


1.4 axios 請(qǐng)求

axios有何優(yōu)點(diǎn),讓vue官網(wǎng)棄用自家的請(qǐng)求方式,推薦用戶(hù)用axios

那么axios的優(yōu)點(diǎn)是什么,往下看

除了以上數(shù)據(jù)請(qǐng)求方式外,還有包括fetch,jsonp等很多方式幫我們處理數(shù)據(jù)請(qǐng)求


2.axios請(qǐng)求了解與基本使用

2.1 axios 請(qǐng)求的特點(diǎn)
  1. 支持node端和瀏覽器端: 同樣的API和措,node和瀏覽器全支持别智,平臺(tái)切換無(wú)壓力
  2. 支持 Promise: 使用Promise管理異步多搀,告別傳統(tǒng)callback方式
  3. 豐富的配置項(xiàng): 支持請(qǐng)求和響應(yīng)的攔截, 提前處理請(qǐng)求和響應(yīng)數(shù)據(jù)


2.2 axios 使用
2.2.1 下載安裝axios包
$ npm install axios


2.2.2 引入使用axios
// 引入包
import axios from "axios"


2.2.3 發(fā)送基本的請(qǐng)求
// 使用axios
axios({
    url:"https://api.github.com/users"
}).then(result => {
    console.log(result);
})

示例中,我們并沒(méi)有請(qǐng)求類(lèi)型, axios默認(rèn)請(qǐng)求為get請(qǐng)求,

如果希望發(fā)送post等其他方式的 請(qǐng)求, 可以在配置對(duì)象中添加method選項(xiàng)

例如:

// 使用post發(fā)送請(qǐng)求
axios({
    url:"https://jsonplaceholder.typicode.com/posts",
    method: "post"
}).then(result => {
    console.log(result);

})


2.2.4 配置對(duì)象中指定get請(qǐng)求參數(shù)

我們可以像傳統(tǒng)get請(qǐng)求傳參一樣在url路徑后拼接請(qǐng)求數(shù)據(jù).

例如:

axios({
  url:"https://jsonplaceholder.typicode.com/posts?userId=1",
}).then(result => {
    console.log(result);
})

也可以將get的請(qǐng)求數(shù)據(jù)放在axios的配置對(duì)象中

例如: 將get請(qǐng)求數(shù)據(jù)放在配置對(duì)象的params選項(xiàng)中

axios({
    url:"https://jsonplaceholder.typicode.com/posts",
    params:{
        userId: 1
    }
}).then(result => {
    console.log(result);

})


3. axios 請(qǐng)求方式

  1. axios(config)

  2. axios.request(config)

  3. axios.get(url[, config])

  4. axios.delete(url[, config])

  5. axios.head(url[, config])

  6. axios.options(url[, config])

  7. axios.post(url[, data[, config]])

  8. axios.put(url[, data[, config]])

  9. axios.patch(url[, data[, config]]

上面基本的示例中,我們是在axios()請(qǐng)求的配置對(duì)象中配置請(qǐng)求方式,axios也提供了通過(guò)不同的方式發(fā)送請(qǐng)求

指定了請(qǐng)求方式發(fā)送請(qǐng)求說(shuō)明

  1. 第一個(gè)參數(shù)將是發(fā)送的url,

  2. 第二個(gè)參數(shù)是請(qǐng)求的配置對(duì)象,可以省略,使用默認(rèn)配置

示例:

不是用配置對(duì)象

axios.get("https://jsonplaceholder.typicode.com/posts?userId=1")
  .then(result => {
     console.log(result);
  })

使用配置對(duì)象

axios.get("https://jsonplaceholder.typicode.com/posts",{
    params:{
        userId:1
    }
}).then(result => {
    console.log(result);
})


4 處理并發(fā)請(qǐng)求

4.1 axios.all 方法處理并發(fā)請(qǐng)求

有的時(shí)候,我們可能需要同時(shí)發(fā)送兩個(gè)請(qǐng)求,需要兩個(gè)結(jié)果都返回了在進(jìn)行數(shù)據(jù)處理

axios提供了一個(gè)all方法幫我們處理并發(fā)請(qǐng)求,使用方式和promiseall方法使用類(lèi)似,出入數(shù)組

例如:

axios.all([
    axios.get("https://jsonplaceholder.typicode.com/posts"),
    axios.post("https://jsonplaceholder.typicode.com/posts")
]).then(resultes => {
    console.log(resultes);

})

數(shù)據(jù)結(jié)果:

并發(fā)請(qǐng)求結(jié)果_圖1.png


4.2 取出數(shù)組中的數(shù)據(jù)

通過(guò)示例,并發(fā)請(qǐng)求返回的結(jié)果是一個(gè)數(shù)組,數(shù)組中包裹不同請(qǐng)求的結(jié)果,

如果把數(shù)據(jù)從數(shù)組中取出,我們可能會(huì)有如下的方法

1.通過(guò)下標(biāo)取值

axios.all([
    axios.get("https://jsonplaceholder.typicode.com/posts"),
    axios.post("https://jsonplaceholder.typicode.com/posts")
]).then(resultes => {
    // 通過(guò)索引拿到不同的數(shù)據(jù)
    let resutl1 = resultes[0];
    let resutl2 = resultes[1];

    console.log(resutl1);
    console.log(resutl2);
})


2.或者使用解構(gòu)取值

axios.all([
    axios.get("https://jsonplaceholder.typicode.com/posts"),
    axios.post("https://jsonplaceholder.typicode.com/posts")
]).then(([resutl1,resutl2]) => {
    // 通過(guò)解構(gòu)取數(shù)據(jù)

    console.log(resutl1);
    console.log(resutl2);
})

以上兩種方法都可以取出數(shù)據(jù)


同樣axios也提供了一個(gè)spread方法把數(shù)據(jù)從數(shù)組中取出

axios.all([
    axios.get("https://jsonplaceholder.typicode.com/posts"),
    axios.post("https://jsonplaceholder.typicode.com/posts")
]).then(axios.spread((resutl1,resutl2) => {
    // 通過(guò)axios的spread方法取出數(shù)據(jù)

    console.log(resutl1);
    console.log(resutl2);
}))


4.3 axios.all 方法的問(wèn)題

axiosall方法和promiseall方法都有一個(gè)致命的缺點(diǎn),就是一點(diǎn)有一個(gè)請(qǐng)求出現(xiàn)錯(cuò)誤,那么整個(gè)請(qǐng)求都會(huì)出現(xiàn)錯(cuò)誤.

但是axiosall方法比promise的好處就是,正常來(lái)說(shuō)服務(wù)器都是連接正常,如果沒(méi)有請(qǐng)求到數(shù)據(jù)也會(huì)返回成功的請(qǐng)求

就算沒(méi)有拿到數(shù)據(jù),本地和服務(wù)器之間的連接也是成功的,只不過(guò)服務(wù)器返回的是其實(shí)數(shù)據(jù)獲取錯(cuò)誤的信息并不是數(shù)據(jù)

無(wú)論如何,在使用時(shí),要注意.


5 axios 請(qǐng)求配置

下面這些是創(chuàng)建請(qǐng)求時(shí)可以用的配置選項(xiàng)。只有 url 是必需的。如果沒(méi)有指定 method,請(qǐng)求將默認(rèn)使用 get 方法。

5.1 常用配置選項(xiàng)

{
   // `url` 是用于請(qǐng)求的服務(wù)器 URL
  url: '/user',

  // `method` 是創(chuàng)建請(qǐng)求時(shí)使用的方法
  method: 'get', // default

  // `baseURL` 將自動(dòng)加在 `url` 前面枫甲,除非 `url` 是一個(gè)絕對(duì) URL。
  // 它可以通過(guò)設(shè)置一個(gè) `baseURL` 便于為 axios 實(shí)例的方法傳遞相對(duì) URL
  baseURL: 'https://some-domain.com/api/',
      
  // `params` 是即將與請(qǐng)求一起發(fā)送的 URL 參數(shù)
  // 必須是一個(gè)無(wú)格式對(duì)象(plain object)或 URLSearchParams 對(duì)象
  params: {
    ID: 12345
  },
      
  // `data` 是作為請(qǐng)求主體被發(fā)送的數(shù)據(jù)
  // 只適用于這些請(qǐng)求方法 'PUT', 'POST', 和 'PATCH'
  // 在沒(méi)有設(shè)置 `transformRequest` 時(shí)扼褪,必須是以下類(lèi)型之一:
  // - string, plain object, ArrayBuffer, ArrayBufferView, URLSearchParams
  // - 瀏覽器專(zhuān)屬:FormData, File, Blob
  // - Node 專(zhuān)屬: Stream
  data: {
    firstName: 'Fred'
  },
      
  // 'proxy' 定義代理服務(wù)器的主機(jī)名稱(chēng)和端口
  // `auth` 表示 HTTP 基礎(chǔ)驗(yàn)證應(yīng)當(dāng)用于連接代理想幻,并提供憑據(jù)
  // 這將會(huì)設(shè)置一個(gè) `Proxy-Authorization` 頭,覆寫(xiě)掉已有的通過(guò)使用 `header` 設(shè)置的自定義 `Proxy-Authorization` 頭话浇。
  proxy: {
    host: '127.0.0.1',
    port: 9000,
    auth: {
      username: 'mikeymike',
      password: 'rapunz3l'
    }
  },

  // `transformRequest` 允許在向服務(wù)器發(fā)送前脏毯,修改請(qǐng)求數(shù)據(jù)
  // 只能用在 'PUT', 'POST' 和 'PATCH' 這幾個(gè)請(qǐng)求方法
  // 后面數(shù)組中的函數(shù)必須返回一個(gè)字符串,或 ArrayBuffer幔崖,或 Stream
  transformRequest: [function (data, headers) {
    // 對(duì) data 進(jìn)行任意轉(zhuǎn)換處理
    return data;
  }],

  // `transformResponse` 在傳遞給 then/catch 前食店,允許修改響應(yīng)數(shù)據(jù)
  transformResponse: [function (data) {
    // 對(duì) data 進(jìn)行任意轉(zhuǎn)換處理
    return data;
  }],

  // `headers` 是即將被發(fā)送的自定義請(qǐng)求頭
  headers: {'X-Requested-With': 'XMLHttpRequest'},

  // `timeout` 指定請(qǐng)求超時(shí)的毫秒數(shù)(0 表示無(wú)超時(shí)時(shí)間)
  // 如果請(qǐng)求話費(fèi)了超過(guò) `timeout` 的時(shí)間渣淤,請(qǐng)求將被中斷
  timeout: 1000,
      
}   


5.2 常用配置示例
axios.all([
    axios({
        baseURL:"https://jsonplaceholder.typicode.com" ,
        url: "/posts",
    }),
    axios({
        baseURL:"https://jsonplaceholder.typicode.com" ,
        url:"/posts/1"
    })
]).then(axios.spread((resutl1,resutl2) => {
    // 通過(guò)axios的spread方法取出數(shù)據(jù)
    console.log(resutl1);
    console.log(resutl2);
}))

每次發(fā)送請(qǐng)求都可以配置當(dāng)前發(fā)送的內(nèi)容


5.3 全局配置

前面講的配置都在在每次發(fā)送請(qǐng)求前進(jìn)行的配置,如果每次發(fā)送都需要用到一些相同的配置,那么我們就可以將這些配置提取出來(lái)成為全局配置

5.3.1 全局配置的方法
// 全局配置基本路徑
axios.defaults.baseURL = "https://jsonplaceholder.typicode.com"
// 全局配置請(qǐng)求頭
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';

一但全局配置,那么每次發(fā)送請(qǐng)求都會(huì)使用全局的配置


5.3.2 使用全局配置修改上面的示例
// 全局配置基本路徑
axios.defaults.baseURL="https://jsonplaceholder.typicode.com" 

// 發(fā)送的兩次請(qǐng)求都會(huì)使用全局配置的路徑
axios.all([
    axios({
        url: "/posts",
    }),
    axios({
        url:"/posts/1"
    })
]).then(axios.spread((resutl1,resutl2) => {
    // 通過(guò)axios的spread方法取出數(shù)據(jù)

    console.log(resutl1);
    console.log(resutl2);
}))

使用全局配置依然可以正常獲取數(shù)據(jù)


6. axios 實(shí)例

6.1 為什么要?jiǎng)?chuàng)建axios實(shí)例

隨著項(xiàng)目的復(fù)雜度的提升,需要的數(shù)據(jù)量就會(huì)越來(lái)越多,出于服務(wù)器性能的考慮, 可能會(huì)將數(shù)據(jù)部署在多臺(tái)服務(wù)器上,

此時(shí)單單只配置一個(gè)全局baseURL以及沒(méi)法滿(mǎn)足我們的需求,

此時(shí)需要使用axios實(shí)例,分別配置對(duì)于不同服務(wù)器數(shù)據(jù)的請(qǐng)求


6.2 創(chuàng)建axios實(shí)例

axios提供了一個(gè)create方法創(chuàng)建實(shí)例

語(yǔ)法格式如下:

const instance = axios.create(config);
// config為當(dāng)前實(shí)例的配置對(duì)象


6.3 axios 實(shí)例的示例

通過(guò)axios向不同的服務(wù)器獲取數(shù)據(jù)

// axios實(shí)例一
// instance 向 jsonplaceholder 發(fā)送請(qǐng)求
const instance = axios.create({
    baseURL: "https://jsonplaceholder.typicode.com" 
})
instance({
    url:"/posts"
}).then(res => {
    console.log(res);
})

// axios 實(shí)例二
// instance2 向 github 發(fā)送請(qǐng)求
const instance2 = axios.create({
    baseURL: "https://api.github.com/users" 
})
instance2({
    url:"/mojombo"
}).then(res => {
    console.log(res);
})


7. axios 封裝

7.1 為什么要對(duì) axios 進(jìn)行封裝

axios封裝原因說(shuō)明

  1. 如果不分裝axios,就在所有需要數(shù)據(jù)的組件中通過(guò)axios發(fā)送請(qǐng)求
  2. 如果未來(lái)需要更換請(qǐng)求的第三方庫(kù),就需更換所有導(dǎo)入axios庫(kù)的組件,
  3. 如果axios請(qǐng)求出現(xiàn)問(wèn)題,需要調(diào)整,就需要在所有使用了axios的組件中進(jìn)行調(diào)整,不利于后期維護(hù)

因此我們需要對(duì)axios進(jìn)行封裝,

這樣所有需要發(fā)送請(qǐng)求的組件都只要使用我們封裝的模塊就可以了,

如果后期需要調(diào)整就只需要修改我們封裝的模塊就可以了


7.2 封裝axios 代碼
import axios from 'axios';

export function request(config){
    const instance = axios.create({
        baseURL: "https://api.github.com/users"
    })

    return instance(config)
}


8. axios 全局?jǐn)r截器

axios在每一個(gè)請(qǐng)求配置中都有一個(gè)配置項(xiàng)用于攔截請(qǐng)求或響應(yīng)結(jié)果

這個(gè)攔截請(qǐng)求只能攔截當(dāng)前配置的請(qǐng)求. 如果我們希望攔截所有的請(qǐng)求,就需要使用全局?jǐn)r截器

全局?jǐn)r截器是會(huì)攔截所有的請(qǐng)求或響應(yīng)


攔截器:就是在請(qǐng)求或響應(yīng)被 thencatch 處理前攔截它們。



// 添加請(qǐng)求攔截器
axios.interceptors.request.use(function (config) {
    // 在發(fā)送請(qǐng)求之前做些什么
    return config;
  }, function (error) {
    // 對(duì)請(qǐng)求錯(cuò)誤做些什么
    return Promise.reject(error);
  });

// 添加響應(yīng)攔截器
axios.interceptors.response.use(function (response) {
    // 對(duì)響應(yīng)數(shù)據(jù)做點(diǎn)什么
    return response;
  }, function (error) {
    // 對(duì)響應(yīng)錯(cuò)誤做點(diǎn)什么
    return Promise.reject(error);
  });


9. 配置的優(yōu)先級(jí)

通過(guò)上面的學(xué)習(xí),知道了axios的配置有以下這些

  1. 默認(rèn)配置,自帶的
  2. 全局配置:axios.defaults.baseURL=""
  3. 實(shí)例配置: axios.create({baseURL:""})
  4. 發(fā)送請(qǐng)求配置:axios({baseURL:""})

這些配置的優(yōu)先級(jí)為

配置以一個(gè)優(yōu)先順序進(jìn)行合并吉嫩。這個(gè)順序是:

  1. lib/defaults.js 找到的庫(kù)的默認(rèn)值价认,

  2. 然后是全局defaults配置

  3. 然后是實(shí)例的 defaults 屬性,

  4. 最后是請(qǐng)求的 config 參數(shù)自娩。

    后者將優(yōu)先于前者用踩。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市忙迁,隨后出現(xiàn)的幾起案子脐彩,更是在濱河造成了極大的恐慌,老刑警劉巖姊扔,帶你破解...
    沈念sama閱讀 207,113評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件惠奸,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡恰梢,警方通過(guò)查閱死者的電腦和手機(jī)佛南,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)删豺,“玉大人共虑,你說(shuō)我怎么就攤上這事愧怜⊙揭常” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 153,340評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵拥坛,是天一觀的道長(zhǎng)蓬蝶。 經(jīng)常有香客問(wèn)我,道長(zhǎng)猜惋,這世上最難降的妖魔是什么丸氛? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,449評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮著摔,結(jié)果婚禮上缓窜,老公的妹妹穿的比我還像新娘。我一直安慰自己谍咆,他們只是感情好禾锤,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著摹察,像睡著了一般恩掷。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上供嚎,一...
    開(kāi)封第一講書(shū)人閱讀 49,166評(píng)論 1 284
  • 那天黄娘,我揣著相機(jī)與錄音峭状,去河邊找鬼。 笑死逼争,一個(gè)胖子當(dāng)著我的面吹牛优床,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播誓焦,決...
    沈念sama閱讀 38,442評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼羔巢,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了罩阵?” 一聲冷哼從身側(cè)響起竿秆,我...
    開(kāi)封第一講書(shū)人閱讀 37,105評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎稿壁,沒(méi)想到半個(gè)月后幽钢,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,601評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡傅是,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評(píng)論 2 325
  • 正文 我和宋清朗相戀三年匪燕,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片喧笔。...
    茶點(diǎn)故事閱讀 38,161評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡帽驯,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出书闸,到底是詐尸還是另有隱情尼变,我是刑警寧澤,帶...
    沈念sama閱讀 33,792評(píng)論 4 323
  • 正文 年R本政府宣布浆劲,位于F島的核電站嫌术,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏牌借。R本人自食惡果不足惜度气,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望膨报。 院中可真熱鬧磷籍,春花似錦、人聲如沸现柠。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,352評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)晒旅。三九已至栅盲,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間废恋,已是汗流浹背谈秫。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,584評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工扒寄, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人拟烫。 一個(gè)月前我還...
    沈念sama閱讀 45,618評(píng)論 2 355
  • 正文 我出身青樓该编,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親硕淑。 傳聞我的和親對(duì)象是個(gè)殘疾皇子课竣,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評(píng)論 2 344