本身動手,爲vue寫一個jsonp的方法

Fetch 提供了對 Request 和 Response (以及其餘與網絡請求有關的)對象通用的定義。它以後可以被使用到不少場景中:service workers、Cache API、其餘處理請求和響應的方式,甚至任何須要生成本身的響應的方式。javascript

衆所周知,fetch提供的請求資源的方法並不包括jsonp,可是咱們又想像使用fetch那樣使用jsonp方法該怎麼辦呢,本文就手把手教你實現一個本身的fetch jsonp方法。源碼在這裏.java

這裏就再也不累述jsonp的原理了,不懂得自行百度或者google吧。git

要本身書寫一個jsonp的方法,是要實現如下幾個模塊:github

  1. 生成script標籤json

  2. 註冊callback函數promise

  3. 返回一個Promise網絡

  4. 移除script標籤閉包

  5. 移除callback函數app


一、生成script標籤

這一部分就直接生成手動操做dom實現就能夠,須要注意的是,爲了方便以後刪除這個script標籤,須要在建立的時候給這個標籤增長一個id屬性。具體代碼以下:dom

function createScript(_url, _id) {
  const script = document.createElement('script');
  script.setAttribute('src', _url);
  script.id = _id;
  document.getElementsByTagName('head')[0].appendChild(script);
}

二、註冊callback函數

註冊callback函數主要是給window添加一個屬性,這個屬性能夠什麼都不用幹,由於畢竟你只須要拿到他的參數,也就是請求的資源就能夠。這裏有一點須要注意就是爲了防止和window原本的屬性衝突,最好取個奇奇怪怪,隨機最好的名字。我取得名字就是jsonp123212這種。代碼以下:

function generateCB() {
  return `jsonp${Math.ceil(Math.random() * 1000000)}`;
}

window[cb] = (res) => {
  alert(res)  //這裏的res就是你想請求的資源
}

三、返回一個promise

這一部分是核心,只有成功的返回了一個promise纔能有機會像fetch那樣的形式去使用。實現的方法就是在callback函數中把返回的結果resolve出去。怎麼resolve出去?callback是全局的函數啊?這個時候就得想一想閉包了,它的存在就是結束這種坑爹的事情的,咱們只要在定時callback的時候讓他能訪問到resolve是否是就解決了呢?是的,具體作法,你看看:

function fetchJsonp(url) {
  return new Promise((resolve, reject)=>{
    window[cb] = (res) => {
      resolve(res)
    }
       createScript() // 這裏就是生成script的函數
  })
}

四、移除script標籤

script標籤用過就不要再留着了,壞處一大堆,爲了優雅咱們就刪了他

function removeScipt(_id) {
  const script = document.getElementById(_id);
  document.getElementsByTagName('head')[0].removeChild(script);
}

五、移除cb函數

script你都移除了,cb更不能留着了啊,這個仍是個全局變量呢,因此刪。

function removeCB(_name) {
  delete window[_name];
}

總結

到這裏都講完了,其實沒什麼難度,主要是本身項目中遇到了jsonp,可是fetch中沒有這個方法啊。因此就想着實現了一個,由於其餘的方法也都封裝,不差這一個了。完整的項目代碼在這裏

還有須要補充的是我直接resolve了,沒有作錯誤處理,也一時想不到什麼錯誤處理,有人想到了能夠告訴我一下。

相關文章
相關標籤/搜索