後續請求都要帶上 token ?

正經寫文章

平時開發裏,先請求一個 token ,而後後面的請求都要帶上這個 token 來進行認證或者受權,是一個常見的需求css

那要怎麼搞呢?仍是一個前後,控制異步流程的的問題,就是先拿到 token 再進行後面的請求就行了。相信 promise 你們已經用得很氾濫了:jquery

let tokenPromise = new Promise(...) // 拿到 token
tokenPromise.then()... // 拿到 token 後去拿數據1
tokenPromise.then()... // 拿到 token 後去拿數據2
tokenPromise.then()... // 拿到 token 後去拿數據3
...

若是向上面這樣組織那就徹底沒問題了。可是實際上通常也不會這樣寫吧,好蠢。。。可是計算機就是用來幫咱們作這種蠢的重複性工做的,咱們稍微變通一下,原理仍是同樣,只是代碼寫好看或者寫少一點就行了ios

假設咱們都是用 XMLHttpRequest 來發起請求的話(誰能告訴我爲何XML是大寫Http卻不是。。。),咱們能夠在 xhr.send() 上作點手腳,把這個函數再包多一層,在裏面叫它幫咱們調用 tokenPromise.then()。先作好準備工做:git

首先我先用 easy-mock 模擬了兩個接口,一個返回 token,一個返回 messagegithub

https://easy-mock.com/mock/5b8fea568eee36669a6b5523/example/token
{
  "data": {
    "token": "a_mock_token"
  }
}

https://easy-mock.com/mock/5b8fea568eee36669a6b5523/example/message
{
  "data": {
    "message": "你好"
  }
}

而後用 jQuery 的 ajax 發請求(只要是用了 XMLHttpRequest 對象,都ok):ajax

<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script>

接下來能夠寫代碼了axios

// 先拿 token
var tokenPromise = new Promise((resovle, reject) => {
  // 清除緩存裏的token
  localStorage.removeItem('token')
  $.ajax({
    type: 'GET',
    url: 'https://easy-mock.com/mock/5b8fea568eee36669a6b5523/example/token',
    success(res) {
      let token = res.data.token
      localStorage.setItem('token', token)
      resovle(token)
    },
    fail(err) {
      reject(err)
    }
  })
})

// 對 xhr.send 再包多一層
var originSend = XMLHttpRequest.prototype.send
XMLHttpRequest.prototype.send = function () {
  var args = arguments
  var self = this
  var fn = function () {
    var token = localStorage.getItem('token')
    // 假如把 token 放在請求頭裏
    self.setRequestHeader('token', token)
    console.log('後續請求token: ', token)
    originSend.apply(self, args)
  }
  // tokenPromise resolved 了纔會執行後續的請求
  tokenPromise.then(fn)
}

// 後續其餘請求, Network 看一下,請求已經帶上 token 了
$.ajax({
  type: 'GET',
  url: 'https://easy-mock.com/mock/5b8fea568eee36669a6b5523/example/message',
  success(res) {
    console.log(res)
  },
  fail(err) {
    console.log(err)
  }
})

完整的代碼小程序

固然這只是一個大概的思路,你要用 axios 而不用 $.ajax ,或者是在小程序裏對 wx.request() 包多一層而不是對 xhr.send() 包多一層都是相似的。但願咱們能寫出更多野雞的寫法promise

自言自語

最近在認真學習 promise,以爲 史上最易讀懂的 Promise/A+ 徹底實現 這篇文章真的挺棒的,起碼能看懂一點了緩存

而後有看到 fly (一個相似於axios的ajax庫)直接就把咱們上述這個先請求 token 的功能寫在文檔裏了,而且這個做者還寫了一個 Ajax-hook 來攔截 ajax 請求

因此就強行給博客拔拔草 :D

相關文章
相關標籤/搜索