axios 後端拿不到引數的處理

雨天Rain發表於2019-02-20

這裡主要想說說常見的,後臺拿不到引數的問題:

  • 用axios建立一個服務(例項方法)

  • post與get請求引數的處理

  • 請求發出前的攔截,後臺拿不到引數怎麼破

ajax庫千萬個,為什麼要選axios?

這個問題就像一個人問你,為什麼你會選擇你的先男(女)朋友?這個問題我是拒絕回答的,畢竟我是個苦逼的單身狗...

網上有很多爭論,比如選擇react、vue還是angular,我也看了很多這些文章,可能很多人都回答,小孩子才做選擇,我們的目標是全都有!

對於這三都沒接觸過的同學,我建議從vue入手,其實我不帶偏見的,選react或者angular也是可以的,但是作為一個過來人(稱不上老司機,對自身技術能力不滿意)來說,熟悉其中一個框架,都能找到工作(其實只有你js基礎好,基礎不好,就看你運氣、簡歷寫得好壞或口才了),不要對網上說哪個框架效能好什麼的就選誰(精力充足的請忽略這句話),剛開始選定一個就足夠了,前端發展太快了,說不定誰陪你到最後,和現在的框架好好過日子就好了,即使因為某種原因不得不換一個框架,對你來說也有很多好處,各個框架都有很多可以互相借鑑的地方,發現這一點,對自身發展也是有好處的

好了,扯遠了,言歸正傳(腦子裡總有那麼多想法,面對喜歡的女孩子的時候,嘴也有那麼多想法就好了,不會經常尬聊,不小心把天聊死)...

咳咳咳

在開發中,為了統一管理和對引數、請求過程發生的錯誤的處理,我們常常定義這樣的一個request.js檔案

用axios建立一個服務(例項方法)

萬事總有個開頭:

// request.js

import axios from 'axios'

// 定義一個常量,就是我們用於請求的服務了
const service = axios.create({
  // 簡單理解就是請求的字首  
  baseURL: '/api/',
  // 預設為post或get
  method: 'post',
  headers: {
    // 該屬性需要和後臺協商或者值為  'application/x-www-form-urlencoded ; charset=UTF-8'
    // 這裡也是可能後臺拿不到引數的原因(後面會說)
    'Content-Type': 'application/json; charset=UTF-8',
  },
  data: {
    usename: 'Jenny',
    country: 'Chinese'
  },
  // 指定請求超時的毫秒數(0 表示無超時時間)
  timeout: 1000 * 60 * 5,
})

exprot default function request (requestConfig) {
  return service(requestConfig)
}

複製程式碼

現在就簡單建立好一個服務了,比如在a.js中使用這個方法:

import sendRequest from './request'

sendRequest({
  // 可不寫,已預設為post
  method: 'post',
  data: {
    usermame: 'Jenny',
  },
  // 如果是get的方法
  // 引數就不是data二是params:
  // params: {
  //    usermame: 'Jenny',
  // }
})

複製程式碼

post與get請求引數的處理

因為一些請求方面的引數用data,有的用params,這樣就不符合統一管理的原則了,所以我們在呼叫的時候,統一把引數作為body這個欄位來使用,在request.js裡面處理就好,所以我們要處理

首先在上面建立的服務之前,寫這樣一個方法來判斷什麼時候將引數的body轉換為data或者params:

// 方法接收一個字元型別的引數,值為請求的方法,判斷是否是post等請求,返回Boolean值
const isPostSeries = (method = 'post') => {
  const requestMethod = method.toLowerCase()
  return requestMethod === 'post' || requestMethod === 'put' || requestMethod === 'patch'
}

// ...

// 改寫這裡:
export default function request (requestConfig) {
  // 呼叫的引數都是body的形式了
  const body = requestConfig.body
  const method = requestConfig.method
  const usePramasKeys = isPostSeries(method)
  // 合併處理引數-如果是post就是 data, 否則params
  // Object.assign這個方法,您需要百度瞭解一下?
  const newRequestConfig = Object.assign(requestConfig, 
  usePramasKeys ? { data: body } : { params: body }
  )
  // 最後把多餘的body刪除掉
  delete combineParams.body
  return service(newRequestConfig)
}

複製程式碼

然後,現在a.js中使用這個方法:

import sendRequest from './request'

sendRequest({
  method: 'post',
  // 引數直接寫body就好了,這樣就不會忘記該用data還是params了吧s
  body: {
    usermame: 'Jenny',
  },
})

複製程式碼

這樣就簡單處理好了

請求發出前的攔截,後臺拿不到引數怎麼破

請求攔截

axios建立例項後,如上面定義的常量service就會有一個屬性interceptors(直譯為攔截器), 該屬性下也有一些屬性,以為對數進行攔截,比如有requestrespose, 顧名思義是對請求和響應的攔截,響應的攔截就是可以對響應值等做一些處理(根據自身的特點), 我這裡主要講後臺拿不到引數的原因,所以講請求的攔截:所以建立axios例項完成以後:

// 首先可能用到一個模組(需要自行安裝):
import Qs from 'qs';

// ...

service.interceptors.request.use(config => {
  // 上面提到contentType是後臺拿不到引數的一個因素(常見的)
  const contentType = config.headers['Content-Type'];

  // 如果後臺接收的contentType值為application/x-www-form-urlencoded 而不是上面預設的 application/json
  // 且為post的請求,要引入qs模組對引數的處理:
  if (isPostSeries(config.method)) {
    config.data = Qs.stringify(config.data)
  }

  // 必須把config給返回出去,這是請求的一些引數,配置,必須的
  return config;
})

// ...
複製程式碼

這裡主要是引入了qs這個模組對post的引數進行處理,後端接收的引數就能成功根據ContentType的型別正確解釋引數了

對引數的處理,其實可以做更多的展開,不過這一個也基本滿足日常需要了

相關文章