日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

Axios 跨端架構是如何實現的?

來源: 責編: 時間:2024-05-07 09:15:51 201觀看
導讀我們都知道,axios 是是一個跨平臺請求方案,在瀏覽器端采用 XMLHttpRequest API 進行封裝,而在 Node.js 端則采用 http/https 模塊進行封裝。axios 內部采用適配器模式將二者合二為一,在隱藏了底層的實現的同時,又對外開放

我們都知道,axios 是是一個跨平臺請求方案,在瀏覽器端采用 XMLHttpRequest API 進行封裝,而在 Node.js 端則采用 http/https 模塊進行封裝。axios 內部采用適配器模式將二者合二為一,在隱藏了底層的實現的同時,又對外開放了一套統一的開放接口。cuq28資訊網——每日最新資訊28at.com

那么本文,我們將來探討這個話題:axios 的跨端架構是如何實現的?cuq28資訊網——每日最新資訊28at.com

從 axios 發送請求說起

我們先來看看 axios 是如何發送請求的。cuq28資訊網——每日最新資訊28at.com

// 發送一個 GET 請求axios({   method: 'get',  url: 'https://jsonplaceholder.typicode.com/comments'  params: { postId: 1 }}) // 發送一個 POST 請求axios({  method: 'post'  url: 'https://jsonplaceholder.typicode.com/posts',  data: {    title: 'foo',    body: 'bar',    userId: 1,  }})

dispatchRequest() 方法

當使用 axios 請求時,實際上內部是由 Axios[3] 實例的 .request() 方法處理的。cuq28資訊網——每日最新資訊28at.com

// /v1.6.8/lib/core/Axios.js#L38async request(configOrUrl, config) {    try {      return await this._request(configOrUrl, config);    } catch (err) {}}

而 ._request() 方法內部會先將  configOrUrl, config 2 個參數處理成 config 參數。cuq28資訊網——每日最新資訊28at.com

// /v1.6.8/lib/core/Axios.js#L62_request(configOrUrl, config) {    if (typeof configOrUrl === 'string') {      config = config || {};      config.url = configOrUrl;    } else {      config = configOrUrl || {};    }    // ...}

這里是為了同時兼容下面 2 種調用方法。cuq28資訊網——每日最新資訊28at.com

// 調用方式一axios('https://jsonplaceholder.typicode.com/posts/1')// 調用方式二axios({  method: 'get',  url: 'https://jsonplaceholder.typicode.com/posts/1'})

當然,這不是重點。在 ._request() 方法內部請求最終會交由 dispatchRequest() 處理。cuq28資訊網——每日最新資訊28at.com

// /v1.6.8/lib/core/Axios.js#L169-L173try {  promise = dispatchRequest.call(this, newConfig);} catch (error) {  return Promise.reject(error);}

dispatchRequest() 是實際調用請求的地方,而實際調用是采用  XMLHttpRequest API(瀏覽器)還是http/https 模塊(Node.js),則需要進一步查看。cuq28資訊網——每日最新資訊28at.com

// /v1.6.8/lib/core/dispatchRequest.js#L34export default function dispatchRequest(config) { /* ... */ }

dispatchRequest() 接收的是上一步合并之后的 config 參數,有了這個參數我們就可以發送請求了。cuq28資訊網——每日最新資訊28at.com

跨端適配實現

// /v1.6.8/lib/core/dispatchRequest.js#L49const adapter = adapters.getAdapter(config.adapter || defaults.adapter);

這里就是我們所說的 axios 內部所使用的適配器模式了。cuq28資訊網——每日最新資訊28at.com

axios 支持從外出傳入 adapter 參數支持自定義請求能力的實現,不過很少使用。大部分請求下,我們都是使用內置的適配器實現。cuq28資訊網——每日最新資訊28at.com

defaults.adapter

defaults.adapter 的值如下:cuq28資訊網——每日最新資訊28at.com

// /v1.6.8/lib/defaults/index.js#L40adapter: ['xhr', 'http'],

adapters.getAdapter(['xhr', 'http']) 又是在做什么事情呢?cuq28資訊網——每日最新資訊28at.com

適配器實現

首先,adapters 位于 lib/adapters/adapters.js[4]。cuq28資訊網——每日最新資訊28at.com

所屬的目錄結構如下:cuq28資訊網——每日最新資訊28at.com

圖片圖片cuq28資訊網——每日最新資訊28at.com

可以看到針對瀏覽器和 Node.js 2 個環境的適配支持:http.js、xhr.js。cuq28資訊網——每日最新資訊28at.com

adapters 的實現如下。cuq28資訊網——每日最新資訊28at.com

首先,將內置的 2 個適配文件引入。cuq28資訊網——每日最新資訊28at.com

// /v1.6.8/lib/adapters/adapters.js#L2-L9import httpAdapter from './http.js';import xhrAdapter from './xhr.js';const knownAdapters = {  http: httpAdapter,  xhr: xhrAdapter}

knownAdapters 的屬性名正好是和 defaults.adapter 的值 ['xhr', 'http'] 是一一對應的。cuq28資訊網——每日最新資訊28at.com

而 adapters.getAdapter(['xhr', 'http']) 的實現是這樣的:cuq28資訊網——每日最新資訊28at.com

// /v1.6.8/lib/adapters/adapters.js#L27-L75export default {  getAdapter: (adapters) => {    // 1)    adapters = Array.isArray(adapters) ? adapters : [adapters];    let nameOrAdapter;    let adapter;        // 2)    for (let i = 0; i < adapters.length; i++) {      nameOrAdapter = adapters[i];      adapter = nameOrAdapter;            // 3)      if (!isResolvedHandle(nameOrAdapter)) {        adapter = knownAdapters[String(nameOrAdapter).toLowerCase()];      }      if (adapter) {        break;      }    }    // 4)    if (!adapter) {      throw new AxiosError(        `There is no suitable adapter to dispatch the request `,        'ERR_NOT_SUPPORT'      );    }    return adapter;  }}

內容比較長,我們會按照代碼標準的序號分 4 個部分來講。cuq28資訊網——每日最新資訊28at.com

1)這里是為了兼容調用 axios() 時傳入 adapter 參數的情況。cuq28資訊網——每日最新資訊28at.com

// `adapter` allows custom handling of requests which makes testing easier.// Return a promise and supply a valid response (see lib/adapters/README.md).adapter: function (config) {  /* ... */},

因為接下來 adapters 是作為數組處理,所以這種場景下,我們將 adapter 封裝成數組 [adapters]。cuq28資訊網——每日最新資訊28at.com

// /v1.6.8/lib/adapters/adapters.js#L28adapters = Array.isArray(adapters) ? adapters : [adapters];

2)接下來,就是遍歷 adapters 找到要用的那個適配器。cuq28資訊網——每日最新資訊28at.com

到目前為止,adapters[i](也就是下面的 nameOrAdapter)既可能是字符串('xhr'、'http'),也可能是函數(function (config) {})。cuq28資訊網——每日最新資訊28at.com

// /v1.6.8/lib/adapters/adapters.js#L37let nameOrAdapter = adapters[i];adapter = nameOrAdapter;

3)那么,我們還要檢查 nameOrAdapter 的類型。cuq28資訊網——每日最新資訊28at.com

// /v1.6.8/lib/adapters/adapters.js#L42-L48if (!isResolvedHandle(nameOrAdapter)) {  adapter = knownAdapters[(id = String(nameOrAdapter)).toLowerCase()];}

isResolvedHandle() 是一個工具函數,其目的是為了判斷是否要從 knownAdapters 獲取適配器。cuq28資訊網——每日最新資訊28at.com

// /v1.6.8/lib/adapters/adapters.js#L24const isResolvedHandle = (adapter) => typeof adapter === 'function' || adapter === null || adapter === false;

簡單理解,只有 adapter 是字符串的情況('xhr' 或 'http'),isResolvedHandle(nameOrAdapter) 才返回 false,才從 knownAdapters 獲得適配器。cuq28資訊網——每日最新資訊28at.com

typeof adapter === 'function' || adapter === null 這個判斷條件我們容易理解,這是為了排除自定義 adapter 參數(傳入函數或 null)的情況。cuq28資訊網——每日最新資訊28at.com

而 adapter === false 又是對應什么情況呢?cuq28資訊網——每日最新資訊28at.com

那是因為我們的代碼只可能是在瀏覽器或 Node.js 環境下運行。這個時候 httpAdapter 和 xhrAdapter 具體返回是有差異的。cuq28資訊網——每日最新資訊28at.com

// /v1.6.8/lib/adapters/xhr.js#L48const isXHRAdapterSupported = typeof XMLHttpRequest !== 'undefined';export default isXHRAdapterSupported && function (config) {/* ...*/}// /v1.6.8/lib/adapters/http.js#L160const isHttpAdapterSupported = typeof process !== 'undefined' && utils.kindOf(process) === 'process';export default isHttpAdapterSupported && function httpAdapter(config) {/* ... */}

也就是說:在瀏覽器環境 httpAdapter 返回 false,xhrAdapter 返回函數;在 Node.js 環境 xhrAdapter 返回 false,httpAdapter 返回函數。cuq28資訊網——每日最新資訊28at.com

因此,一旦 isResolvedHandle() 邏輯執行完成后。cuq28資訊網——每日最新資訊28at.com

if (!isResolvedHandle(nameOrAdapter)) {/* ... */}

會檢查 adapter 變量的值,一旦有值(非 false)就說明找到適配器了,結束遍歷。cuq28資訊網——每日最新資訊28at.com

if (adapter) {  break;}

4)最終在返回適配器前做空檢查cuq28資訊網——每日最新資訊28at.com

// 4)if (!adapter) {  throw new AxiosError(    `There is no suitable adapter to dispatch the request `,    'ERR_NOT_SUPPORT'  );}return adapter;

如此,就完成了跨端架構的實現。cuq28資訊網——每日最新資訊28at.com

總結

本文我們講述了 axios 的跨端架構原理。axios 內部實際發出請求是通過 dispatchRequest() 方法處理的,再往里看則是通過適配器模式取得適應于當前環境的適配器函數。cuq28資訊網——每日最新資訊28at.com

axios 內置了 2 個適配器支持:httpAdapter 和 xhrAdapter。httpAdapter 是 Node.js 環境實現,通過 http/https 模塊;xhrAdapter 這是瀏覽器環境實現,通過 XMLHttpRequest API 實現。Node.js 環境 xhrAdapter 返回 false,瀏覽器環境 httpAdapter 返回 false——這樣總是能返回正確的適配器。cuq28資訊網——每日最新資訊28at.com

參考資料

[1]axios 是如何實現取消請求的?: https://juejin.cn/post/7359444013894811689cuq28資訊網——每日最新資訊28at.com

[2]你知道嗎?axios 請求是 JSON 響應優先的: https://juejin.cn/post/7359580605320036415cuq28資訊網——每日最新資訊28at.com

[3]Axios: https://github.com/axios/axios/blob/v1.6.8/lib/core/Axios.jscuq28資訊網——每日最新資訊28at.com

[4]lib/adapters/adapters.js: https://github.com/axios/axios/blob/v1.6.8/lib/adapters/adapters.jscuq28資訊網——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-87048-0.htmlAxios 跨端架構是如何實現的?

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 盤點Lombok的幾個操作,你記住了嗎?

下一篇: Python 網絡爬蟲利器:執行 JavaScript 實現數據抓取

標簽:
  • 熱門焦點
  • 中興AX5400Pro+上手體驗:再升級 雙2.5G網口+USB 3.0這次全都有

    2021年11月的時候,中興先后發布了兩款路由器產品,中興AX5400和中興AX5400 Pro,從產品命名上就不難看出這是隸屬于同一系列的,但在外觀設計上這兩款產品可以說是完全沒一點關系
  • Golang 中的 io 包詳解:組合接口

    io.ReadWriter// ReadWriter is the interface that groups the basic Read and Write methods.type ReadWriter interface { Reader Writer}是對Reader和Writer接口的組合,
  • JavaScript學習 -AES加密算法

    引言在當今數字化時代,前端應用程序扮演著重要角色,用戶的敏感數據經常在前端進行加密和解密操作。然而,這樣的操作在網絡傳輸和存儲中可能會受到惡意攻擊的威脅。為了確保數據
  • 每天一道面試題-CPU偽共享

    前言:了不起:又到了每天一到面試題的時候了!學弟,最近學習的怎么樣啊 了不起學弟:最近學習的還不錯,每天都在學習,每天都在進步! 了不起:那你最近學習的什么呢? 了不起學弟:最近在學習C
  • 小紅書1周漲粉49W+,我總結了小白可以用的N條漲粉筆記

    作者:黃河懂運營一條性教育視頻,被54萬人&ldquo;珍藏&rdquo;是什么體驗?最近,情感博主@公主是用鮮花做的,火了!僅僅憑借一條視頻,光小紅書就有超過128萬人,為她瘋狂點贊!更瘋狂的是,這
  • 梁柱接棒兩年,騰訊音樂闖出新路子

    文丨田靜 出品丨牛刀財經(niudaocaijing)7月5日,企鵝FM發布官方公告稱由于業務調整,將于9月6日正式停止運營,這意味著騰訊音樂長音頻業務走向消亡。騰訊在長音頻領域還在摸索。為
  • 網紅炒股不為了賺錢,那就是耍流氓!

    來源:首席商業評論6月26日高調宣布入市,網絡名嘴大v胡錫進居然進軍了股市。在一次財經媒體峰會上,幾個財經圈媒體大佬就&ldquo;胡錫進炒股是否知道認真報道&rdquo;展開討論。有
  • 三翼鳥智能家居亮相電博會,讓用戶體驗更真實

    2021電博會在青島國際會展中心開幕中,三翼鳥直接把“家”搬到了現場,成為了展會的一大看點。這也是三翼鳥繼9月9日發布了行業首個一站式定制智慧家平臺后的
  • 利用職權私自解除被封帳號 Meta開除20多名員工

    11月18日消息,據外媒援引知情人士表示,過去一年時間內,Facebook母公司Meta解雇或處罰了20多名員工以及合同工,指控這些人通過內部系統以不當方式重置用戶帳號,其
Top 主站蜘蛛池模板: 柳林县| 固安县| 宁河县| 兴隆县| 新巴尔虎左旗| 清镇市| 朔州市| 华容县| 满城县| 广灵县| 连云港市| 武功县| 深泽县| 望都县| 萍乡市| 纳雍县| 芷江| 荣成市| 玉龙| 崇阳县| 宜川县| 库伦旗| 开平市| 阜平县| 社旗县| 礼泉县| 武义县| 惠安县| 东乡县| 左云县| 全南县| 中西区| 菏泽市| 开鲁县| 罗田县| 南京市| 江城| 武宣县| 东平县| 萨嘎县| 鸡泽县|