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

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

Axios Node 端請求是如何實現的?

來源: 責編: 時間:2024-06-05 17:41:33 147觀看
導讀本文我們將討論 axios 的 Node 環境實現。我們都知道使用 axios 可以讓我們在瀏覽器和 Node 端獲得一致的使用體驗。這部分是通過適配器模式來實現的。axios 內置了 2 個適配器(截止到 v1.6.8 版本)[8]:xhr.js 和 http.j
本文我們將討論 axios 的 Node 環境實現。我們都知道使用 axios 可以讓我們在瀏覽器和 Node 端獲得一致的使用體驗。這部分是通過適配器模式來實現的。

axios 內置了 2 個適配器(截止到 v1.6.8 版本)[8]:xhr.js 和 http.js。7Rj28資訊網——每日最新資訊28at.com

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

顧名思義,xhr.js 是針對瀏覽器環境提供的 XMLHttpRequest 封裝的;http.js 則是針對 Node 端的 http/https 模塊進行封裝的。7Rj28資訊網——每日最新資訊28at.com

不久前,我們詳細講解了瀏覽器端的實現,本文就來看看 Node 環境又是如何實現的。7Rj28資訊網——每日最新資訊28at.com

Node 端請求案例

老規矩,在介紹實現之前,先看看 axios 在瀏覽器器環境的使用。7Rj28資訊網——每日最新資訊28at.com

首先創建項目,安裝 axios 依賴:7Rj28資訊網——每日最新資訊28at.com

mdir axios-demoscd axios-demosnpm initnpm install axios# 使用 VS Code 打開當前目錄code .

寫一個測試文件 index.js:7Rj28資訊網——每日最新資訊28at.com

// index.jsconst axios = require('axios')axios.get('https://httpstat.us/200')  .then(res => {    console.log('res >>>>', res)  })

執行文件:7Rj28資訊網——每日最新資訊28at.com

node --watch index.js

注意:--watch[9] 是 Node.js 在 v16.19.0 版本引入的實驗特性,在 v22.0.0 已轉為正式特性。7Rj28資訊網——每日最新資訊28at.com

打印出來結果類似:7Rj28資訊網——每日最新資訊28at.com

Restarting 'index.js'res >>>> {  status: 200,  statusText: 'OK'  headers: Object [AxiosHeaders] {}  config: {}  request: <ref *1> ClientRequest {}  data: { code: 200, description: 'OK' }}Completed running 'index.js'

修改 Index.js 文件內容保存:7Rj28資訊網——每日最新資訊28at.com

const axios = require('axios')axios.get('https://httpstat.us/404')  .catch(err => {    console.log('err >>>>', err)  })

打印結果類似:7Rj28資訊網——每日最新資訊28at.com

Restarting 'index.js'err >>>> AxiosError: Request failed with status code 404 {  code: 'ERR_BAD_REQUEST',  config: {}  request: <ref *1> ClientRequest {}  response: {    status: 404,    statusText: 'Not Found',    data: { code: 404, description: 'Not Found' }  }}

以上我們就算講完了 axios 在 Node 端的簡單使用,這就是 axios 好處所在,統一的使用體驗,免去了我們在跨平臺的學習成本,提升了開發體驗。7Rj28資訊網——每日最新資訊28at.com

源碼分析

接下來就來看看 axios 的 Node 端實現。源代碼位于 lib/adapters/http.js[10] 下。7Rj28資訊網——每日最新資訊28at.com

// /v1.6.8/lib/adapters/http.js#L160export default isHttpAdapterSupported && function httpAdapter(config) {/* ... */}

Node 端發出的請求最終都是交由 httpAdapter(config) 函數處理的,其核心實現如下:7Rj28資訊網——每日最新資訊28at.com

import http from 'http';import https from 'https';export default isHttpAdapterSupported && function httpAdapter(config) {  // 1)  return wrapAsync(async function dispatchHttpRequest(resolve, reject, onDone) {        // 2)    let {data, lookup, family} = config;    const {responseType, responseEncoding} = config;    const method = config.method.toUpperCase();        // Parse url    const fullPath = buildFullPath(config.baseURL, config.url);    const parsed = new URL(fullPath, 'http://localhost');        const headers = AxiosHeaders.from(config.headers).normalize();        if (data && !utils.isStream(data)) {      if (Buffer.isBuffer(data)) {        // Nothing to do...      } else if (utils.isArrayBuffer(data)) {        data = Buffer.from(new Uint8Array(data));      } else if (utils.isString(data)) {        data = Buffer.from(data, 'utf-8');      } else {        return reject(new AxiosError(          'Data after transformation must be a string, an ArrayBuffer, a Buffer, or a Stream',          AxiosError.ERR_BAD_REQUEST,          config        ));      }    }        const options = {      path,      method: method,      headers: headers.toJSON(),      agents: { http: config.httpAgent, https: config.httpsAgent },      auth,      protocol,      family,      beforeRedirect: dispatchBeforeRedirect,      beforeRedirects: {}    };        // 3)      let transport;    const isHttpsRequest = /https:?/.test(options.protocol);        if (config.maxRedirects === 0) {      transport = isHttpsRequest ? https : http;    }        // Create the request    req = transport.request(options, function handleResponse(res) {      // ...    }        // 4)    // Handle errors    req.on('error', function handleRequestError(err) {      // @todo remove      // if (req.aborted && err.code !== AxiosError.ERR_FR_TOO_MANY_REDIRECTS) return;      reject(AxiosError.from(err, null, config, req));    });        // 5)    // Handle request timeout    if (config.timeout) {      req.setTimeout(timeout, function handleRequestTimeout() {        if (isDone) return;        let timeoutErrorMessage = config.timeout ? 'timeout of ' + config.timeout + 'ms exceeded' : 'timeout exceeded';        const transitional = config.transitional || transitionalDefaults;        if (config.timeoutErrorMessage) {          timeoutErrorMessage = config.timeoutErrorMessage;        }        reject(new AxiosError(          timeoutErrorMessage,          transitional.clarifyTimeoutError ? AxiosError.ETIMEDOUT : AxiosError.ECONNABORTED,          config,          req        ));        abort();      });    }        // 6)    // Send the request    if (utils.isStream(data)) {      let ended = false;      let errored = false;      data.on('end', () => {        ended = true;      });      data.once('error', err => {        errored = true;        req.destroy(err);      });      data.on('close', () => {        if (!ended && !errored) {          abort(new CanceledError('Request stream has been aborted', config, req));        }      });      data.pipe(req);    } else {      req.end(data);    }  }

是有點長,但大概瀏覽一遍就行,后面會詳細講。實現主要有 6 部分:7Rj28資訊網——每日最新資訊28at.com

  1. 這里的 wrapAsync 是對 return new Promise((resolve, resolve) => {}) 的包裝,暴露出 resolve、reject 供 dispatchHttpRequest 函數內部調用使用,代表請求成功或失敗
  2. 接下里,就是根據傳入的 config 信息組裝請求參數 options 了
  3. axios 會根據傳入的 url 的協議,決定是采用 http 還是 https 模塊創建請求
  4. 監聽請求 req 上的異常(error)事件
  5. 跟 4) 一樣,不過監聽的是請求 req 上的超時事件。而其他諸如取消請求、完成請求等其他兼容事件則是在 2) 創建請求的回調函數 handleResponse(res) 中處理的
  6. 最后,調用 req.end(data) 發送請求即可。當然,這里會針對 data 是 Stream 類型的情況特別處理一下

大概介紹了之后,我們再深入每一步具體學習一下。7Rj28資訊網——每日最新資訊28at.com

包裝函數 wrapAsync

首先,httpAdapter(config) 內部的實現是經過 wrapAsync 包裝函數返回的。7Rj28資訊網——每日最新資訊28at.com

// /v1.6.8/lib/adapters/http.js#L122-L145const wrapAsync = (asyncExecutor) => {  return new Promise((resolve, reject) => {    let onDone;    let isDone;    const done = (value, isRejected) => {      if (isDone) return;      isDone = true;      onDone && onDone(value, isRejected);    }    const _resolve = (value) => {      done(value);      resolve(value);    };    const _reject = (reason) => {      done(reason, true);      reject(reason);    }    asyncExecutor(_resolve, _reject, (onDoneHandler) => (onDone = onDoneHandler)).catch(_reject);  })};

調用 wrapAsync 函數會返回一個 Promise 對象,除了跟原生 Promise 構造函數一樣會返回 resolve、reject 之外,還額外拓展了一個 onDone 參數,確保 Promise 狀態改變后,總是會調用 onDone。7Rj28資訊網——每日最新資訊28at.com

組裝請求參數

在處理好返回值后,接下來要做的就是組裝請求參數了,請求參數最終會交由 http.request(options)[11]/https.request(options)[12] 處理,因此需要符合其類型定義。7Rj28資訊網——每日最新資訊28at.com

http 模塊的請求案例

在理解 options 參數之前,先了解一下 http 模塊的請求案例。7Rj28資訊網——每日最新資訊28at.com

const http = require('node:http');const options = {  hostname: 'www.google.com',  port: 80,  path: '/upload',  method: 'POST',  headers: {    'Content-Type': 'application/json',    'Content-Length': Buffer.byteLength(postData),  },};const req = http.request(options, (res) => {  console.log(`STATUS: ${res.statusCode}`);  console.log(`HEADERS: ${JSON.stringify(res.headers)}`);  res.setEncoding('utf8');  res.on('data', (chunk) => {    console.log(`BODY: ${chunk}`);  });  res.on('end', () => {    console.log('No more data in response.');  });});req.on('error', (e) => {  console.error(`problem with request: ${e.message}`);});req.end(JSON.stringify({  'msg': 'Hello World!',}));

以上,我們向 http://www.google.com/upload 發起了一個 POST 請求(https 請求與此類次)。7Rj28資訊網——每日最新資訊28at.com

值得注意的是,請求參數 options 中并不包含請求體數據,請求體數據最終是以 req.end(data) 發動出去的,這一點跟 XMLHttpRequest 實例的做法類似。7Rj28資訊網——每日最新資訊28at.com

組裝請求參數

再來看看 axios 中關于這塊請求參數的組裝邏輯。7Rj28資訊網——每日最新資訊28at.com

首先,使用 .baseURL 和 .url 參數解析出跟 URL 相關數據。7Rj28資訊網——每日最新資訊28at.com

/v1.6.8/lib/adapters/http.js#L221// Parse urlconst fullPath = buildFullPath(config.baseURL, config.url);const parsed = new URL(fullPath, 'http://localhost');const protocol = parsed.protocol || supportedProtocols[0];

不支持的請求協議會報錯。7Rj28資訊網——每日最新資訊28at.com

// /v1.6.8/lib/platform/node/index.js#L11protocols: [ 'http', 'https', 'file', 'data' ]// /v1.6.8/lib/adapters/http.js#L44const supportedProtocols = platform.protocols.map(protocol => {  return protocol + ':';});// /v1.6.8/lib/adapters/http.js#L265-L271if (supportedProtocols.indexOf(protocol) === -1) {  return reject(new AxiosError(    'Unsupported protocol ' + protocol,    AxiosError.ERR_BAD_REQUEST,    config  ));}

錯誤 CODE 是 ERR_BAD_REQUEST,類似 4xx 錯誤。7Rj28資訊網——每日最新資訊28at.com

接下來,將 headers 參數轉成 AxiosHeaders 實例。7Rj28資訊網——每日最新資訊28at.com

// /v1.6.8/lib/adapters/http.js#L273const headers = AxiosHeaders.from(config.headers).normalize();

最后,處理下請求體數據 config.data。7Rj28資訊網——每日最新資訊28at.com

// /v1.6.8/lib/adapters/http.js#L287-L326// support for spec compliant FormData objectsif (utils.isSpecCompliantForm(data)) {  const userBoundary = headers.getContentType(/boundary=([-_/w/d]{10,70})/i);  data = formDataToStream(data, (formHeaders) => {    headers.set(formHeaders);  }, {    tag: `axios-${VERSION}-boundary`,    boundary: userBoundary && userBoundary[1] || undefined  });  // support for https://www.npmjs.com/package/form-data api} else if (utils.isFormData(data) && utils.isFunction(data.getHeaders)) {  headers.set(data.getHeaders());  if (!headers.hasContentLength()) {    try {      const knownLength = await util.promisify(data.getLength).call(data);      Number.isFinite(knownLength) && knownLength >= 0 && headers.setContentLength(knownLength);      /*eslint no-empty:0*/    } catch (e) {    }  }} else if (utils.isBlob(data)) {  data.size && headers.setContentType(data.type || 'application/octet-stream');  headers.setContentLength(data.size || 0);  data = stream.Readable.from(readBlob(data));} else if (data && !utils.isStream(data)) {  if (Buffer.isBuffer(data)) {    // Nothing to do...  } else if (utils.isArrayBuffer(data)) {    data = Buffer.from(new Uint8Array(data));  } else if (utils.isString(data)) {    data = Buffer.from(data, 'utf-8');  } else {    return reject(new AxiosError(      'Data after transformation must be a string, an ArrayBuffer, a Buffer, or a Stream',      AxiosError.ERR_BAD_REQUEST,      config    ));  }

axios 會針對傳入的不同類型的 config.data 做統一處理,最終不是處理成 Stream 就是處理成 Buffer。7Rj28資訊網——每日最新資訊28at.com

不過,當傳入的 data 是對象時,在調用 httpAdapter(config) 之前,會先經過 transformRequest() 函數處理成字符串。7Rj28資訊網——每日最新資訊28at.com

// /v1.6.8/lib/defaults/index.js#L91-L94if (isObjectPayload || hasJSONContentType ) {  headers.setContentType('application/json', false);  return stringifySafely(data);}

針對這個場景,data 會進入到下面的處理邏輯,將字符串處理成 Buffer。7Rj28資訊網——每日最新資訊28at.com

// /v1.6.8/lib/adapters/http.js#L287-L326if (utils.isString(data)) {  data = Buffer.from(data, 'utf-8');}

然后,獲得請求路徑 path。7Rj28資訊網——每日最新資訊28at.com

// /v1.6.8/lib/adapters/http.js#L384C4-L397C1try {  path = buildURL(    parsed.pathname + parsed.search,    config.params,    config.paramsSerializer  ).replace(/^/?/, '');} catch (err) {   // ...}

最后,組裝 options 參數。7Rj28資訊網——每日最新資訊28at.com

// /v1.6.8/lib/adapters/http.js#L403C1-L413C7const options = {  path,  method: method,  headers: headers.toJSON(),  agents: { http: config.httpAgent, https: config.httpsAgent },  auth,  protocol,  family,  beforeRedirect: dispatchBeforeRedirect,  beforeRedirects: {}};

創建請求

再看創建請求環節。7Rj28資訊網——每日最新資訊28at.com

獲得請求實例

首先,是獲得請求實例。7Rj28資訊網——每日最新資訊28at.com

import followRedirects from 'follow-redirects';const {http: httpFollow, https: httpsFollow} = followRedirects;// /v1.6.8/lib/adapters/http.js#L426-L441let transport;const isHttpsRequest = isHttps.test(options.protocol);options.agent = isHttpsRequest ? config.httpsAgent : config.httpAgent;if (config.transport) {  transport = config.transport;} else if (config.maxRedirects === 0) {  transport = isHttpsRequest ? https : http;} else {  if (config.maxRedirects) {    options.maxRedirects = config.maxRedirects;  }  if (config.beforeRedirect) {    options.beforeRedirects.config = config.beforeRedirect;  }  transport = isHttpsRequest ? httpsFollow : httpFollow;}

如上所示,你可以通過 config.transport 傳入,但通常不會這么做。否則,axios 內部會根據你是否傳入 config.maxRedirects(默認 undefined) 決定使用原生 http/https 模塊還是 follow-redirects 包里提供的 http/https 方法。7Rj28資訊網——每日最新資訊28at.com

如果沒有傳入 config.maxRedirects,axios 默認會使用 follow-redirects 包里提供的 http/https 方法發起請求,它的用法跟原生 http/https 模塊一樣,這里甚至可以只使用 follow-redirects 就夠了。7Rj28資訊網——每日最新資訊28at.com

創建請求

下面就是創建請求了。7Rj28資訊網——每日最新資訊28at.com

// Create the requestreq = transport.request(options, function handleResponse(res) {}

我們在 handleResponse 回調函數里處理返回數據 res。7Rj28資訊網——每日最新資訊28at.com

function request(options: RequestOptions | string | URL, callback?: (res: IncomingMessage) => void): ClientRequest;function request(    url: string | URL,    options: RequestOptions,    callback?: (res: IncomingMessage) => void,): ClientRequest;

根據定義,我們知道 res 是 IncomingMessage 類型,繼承自 stream.Readable[13],是一種可讀的 Stream。7Rj28資訊網——每日最新資訊28at.com

const readable = getReadableStreamSomehow();readable.on('data', (chunk) => {  console.log(`Received ${chunk.length} bytes of data.`);});

res 的處理我們會放到處理請求一節講述,下面就是發出請求了。7Rj28資訊網——每日最新資訊28at.com

發出請求

這部分代碼比較簡單,而數據體也是在這里傳入的。7Rj28資訊網——每日最新資訊28at.com

// /v1.6.8/lib/adapters/http.js#L658C5-L681C6// Send the requestif (utils.isStream(data)) {  let ended = false;  let errored = false;  data.on('end', () => {    ended = true;  });  data.once('error', err => {    errored = true;    req.destroy(err);  });  data.on('close', () => {    if (!ended && !errored) {      abort(new CanceledError('Request stream has been aborted', config, req));    }  });  data.pipe(req);} else {  req.end(data);}

如果你的請求體是 Buffer 類型的,那么直接傳入 req.end(data) 即可,否則(Stream 類型)則需要以管道形式傳遞給 req。7Rj28資訊網——每日最新資訊28at.com

處理請求

接著創建請求一節,下面開始分析請求的處理。7Rj28資訊網——每日最新資訊28at.com

Node.js 部分的請求處理,比處理 XMLHttpRequest 稍微復雜一些。你要在 2 個地方做監聽處理。7Rj28資訊網——每日最新資訊28at.com

  1. transport.request 返回的 req 實例
  2. 另一個,則是 transport.request 回調函數 handleResponse 返回的 res(也就是 responseStream)

監聽 responseStream

首先,用 res/responseStream 上已有的信息組裝響應數據 response。7Rj28資訊網——每日最新資訊28at.com

// /v1.6.8/lib/adapters/http.js#L478// decompress the response body transparently if requiredlet responseStream = res;// return the last request in case of redirectsconst lastRequest = res.req || req;const response = {  status: res.statusCode,  statusText: res.statusMessage,  headers: new AxiosHeaders(res.headers),  config,  request: lastRequest};

這是不完整的,因為我們還沒有設置 response.data。7Rj28資訊網——每日最新資訊28at.com

// /v1.6.8/lib/adapters/http.js#L535C7-L538C15if (responseType === 'stream') {  response.data = responseStream;  settle(resolve, reject, response);} else {  // ...}

如果用戶需要的是響應類型是 stream,那么一切就變得簡單了,直接將數據都給 settle 函數即可。7Rj28資訊網——每日最新資訊28at.com

// /v1.6.8/lib/core/settle.jsexport default function settle(resolve, reject, response) {  const validateStatus = response.config.validateStatus;  if (!response.status || !validateStatus || validateStatus(response.status)) {    resolve(response);  } else {    reject(new AxiosError(      'Request failed with status code ' + response.status,      [AxiosError.ERR_BAD_REQUEST, AxiosError.ERR_BAD_RESPONSE][Math.floor(response.status / 100) - 4],      response.config,      response.request,      response    ));  }}

settle 函數會根據傳入的 response.status 和 config.validateStatus() 決定請求是成功(resolve)還是失敗(reject)。7Rj28資訊網——每日最新資訊28at.com

當然,如果需要的響應類型不是 stream,就監聽 responseStream 對象上的事件,處理請求結果。7Rj28資訊網——每日最新資訊28at.com

// /v1.6.8/lib/adapters/http.js#L538C1-L591C8} else {  const responseBuffer = [];  let totalResponseBytes = 0;  // 1)  responseStream.on('data', function handleStreamData(chunk) {    responseBuffer.push(chunk);    totalResponseBytes += chunk.length;    // make sure the content length is not over the maxContentLength if specified    if (config.maxContentLength > -1 && totalResponseBytes > config.maxContentLength) {      // stream.destroy() emit aborted event before calling reject() on Node.js v16      rejected = true;      responseStream.destroy();      reject(new AxiosError('maxContentLength size of ' + config.maxContentLength + ' exceeded',        AxiosError.ERR_BAD_RESPONSE, config, lastRequest));    }  });    // 2)  responseStream.on('aborted', function handlerStreamAborted() {    if (rejected) {      return;    }    const err = new AxiosError(      'maxContentLength size of ' + config.maxContentLength + ' exceeded',      AxiosError.ERR_BAD_RESPONSE,      config,      lastRequest    );    responseStream.destroy(err);    reject(err);  });  // 3)  responseStream.on('error', function handleStreamError(err) {    if (req.destroyed) return;    reject(AxiosError.from(err, null, config, lastRequest));  });    // 4)  responseStream.on('end', function handleStreamEnd() {    try {      let responseData = responseBuffer.length === 1 ? responseBuffer[0] : Buffer.concat(responseBuffer);      if (responseType !== 'arraybuffer') {        responseData = responseData.toString(responseEncoding);        if (!responseEncoding || responseEncoding === 'utf8') {          responseData = utils.stripBOM(responseData);        }      }      response.data = responseData;    } catch (err) {      return reject(AxiosError.from(err, null, config, response.request, response));    }    settle(resolve, reject, response);  });}

responseStream 上會監聽 4 個事件。7Rj28資訊網——每日最新資訊28at.com

  1. data:Node 請求的響應默認都是以流數據形式接收的,而 data 就是在接收過程中會不斷觸發的事件。我們在這里將接收到的數據存儲在 responseBuffer 中,以便后續使用
  2. aborted:會在接收響應數據超過時,或是調用 .destory() 時觸發
  3. err:在流數據接收錯誤時調用
  4. end:數據結束接收,將收集到的 responseBuffer 先轉換成 Buffer 類型,再轉換成字符串,最終賦值給 response.data

監聽 req

以上,我們完成了對響應數據的監聽。我們再來看看,對請求實例 req 的監聽。7Rj28資訊網——每日最新資訊28at.com

// /v1.6.8/lib/adapters/http.js#L606// Handle errorsreq.on('error', function handleRequestError(err) {  // @todo remove  // if (req.aborted && err.code !== AxiosError.ERR_FR_TOO_MANY_REDIRECTS) return;  reject(AxiosError.from(err, null, config, req));});// /v1.6.8/lib/adapters/http.js#L619// Handle request timeoutif (config.timeout) {  req.setTimeout(timeout, function handleRequestTimeout() {    if (isDone) return;    let timeoutErrorMessage = config.timeout ? 'timeout of ' + config.timeout + 'ms exceeded' : 'timeout exceeded';    const transitional = config.transitional || transitionalDefaults;    if (config.timeoutErrorMessage) {      timeoutErrorMessage = config.timeoutErrorMessage;    }    reject(new AxiosError(      timeoutErrorMessage,      transitional.clarifyTimeoutError ? AxiosError.ETIMEDOUT : AxiosError.ECONNABORTED,      config,      req    ));    abort();  });}

一共監聽了 2 個事件:7Rj28資訊網——每日最新資訊28at.com

  1. error:請求出錯
  2. req.setTimeout():請求超時

以上,我們就完成了請求處理的所有內容。可以發現,Node 端處理請求的邏輯會比瀏覽器端稍微復雜一些:你需要同時監聽請求實例以及響應流數據上的事件,確保整個請求過程被完整監聽。7Rj28資訊網——每日最新資訊28at.com

總結

本文主要帶大家學習了 axios 的 Node 端實現。7Rj28資訊網——每日最新資訊28at.com

相比較于瀏覽器端要稍微復雜一些,不僅是因為我們要考慮請求可能的最大跳轉(maxRedirects),還要同時監聽請求實例以及響應流數據上的事件,確保整個請求過程被完整監聽。7Rj28資訊網——每日最新資訊28at.com

參考資料

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

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

[3]axios 跨端架構是如何實現的?: https://juejin.cn/post/73621198486604513917Rj28資訊網——每日最新資訊28at.com

[4]axios 攔截器機制是如何實現的?: https://juejin.cn/post/73635457378741617037Rj28資訊網——每日最新資訊28at.com

[5]axios 瀏覽器端請求是如何實現的?: https://juejin.cn/post/73639285690288210297Rj28資訊網——每日最新資訊28at.com

[6]axios 對外出口API是如何設計的?: https://juejin.cn/post/73646143373713080717Rj28資訊網——每日最新資訊28at.com

[7]axios 中是如何處理異常的?: https://juejin.cn/post/73699510851947397757Rj28資訊網——每日最新資訊28at.com

[8]axios 內置了 2 個適配器(截止到 v1.6.8 版本): https://github.com/axios/axios/tree/v1.6.8/lib/adapters7Rj28資訊網——每日最新資訊28at.com

[9]--watch: https://nodejs.org/api/cli.html#--watch7Rj28資訊網——每日最新資訊28at.com

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

[11]http.request(options): https://nodejs.org/docs/latest/api/http.html#httprequestoptions-callback7Rj28資訊網——每日最新資訊28at.com

[12]https.request(options): https://nodejs.org/docs/latest/api/https.html#httpsrequestoptions-callback7Rj28資訊網——每日最新資訊28at.com

[13]stream.Readable: https://nodejs.org/docs/latest/api/stream.html#class-streamreadable7Rj28資訊網——每日最新資訊28at.com

7Rj28資訊網——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-92115-0.htmlAxios Node 端請求是如何實現的?

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

上一篇: Go 新提案:用 #err 標識符去做錯誤處理!

下一篇: 被嚴重低估!React 19 又是一次開發方式的變革,useEffect 將會逐漸退出歷史舞臺

標簽:
  • 熱門焦點
  • 7月安卓手機性能榜:紅魔8S Pro再奪榜首

    7月份的手機市場風平浪靜,除了紅魔和努比亞帶來了兩款搭載驍龍8Gen2領先版處理器的新機之外,別的也想不到有什么新品了,這也正常,通常6月7月都是手機廠商修整的時間,進入8月份之
  • 把LangChain跑起來的三個方法

    使用LangChain開發LLM應用時,需要機器進行GLM部署,好多同學第一步就被勸退了,那么如何繞過這個步驟先學習LLM模型的應用,對Langchain進行快速上手?本片講解3個把LangChain跑起來
  • 如何正確使用:Has和:Nth-Last-Child

    我們可以用CSS檢查,以了解一組元素的數量是否小于或等于一個數字。例如,一個擁有三個或更多子項的grid。你可能會想,為什么需要這樣做呢?在某些情況下,一個組件或一個布局可能會
  • Java NIO內存映射文件:提高文件讀寫效率的優秀實踐!

    Java的NIO庫提供了內存映射文件的支持,它可以將文件映射到內存中,從而可以更快地讀取和寫入文件數據。本文將對Java內存映射文件進行詳細的介紹和演示。內存映射文件概述內存
  • 使用LLM插件從命令行訪問Llama 2

    最近的一個大新聞是Meta AI推出了新的開源授權的大型語言模型Llama 2。這是一項非常重要的進展:Llama 2可免費用于研究和商業用途。(幾小時前,swyy發現它已從LLaMA 2更名為Lla
  • 10天營收超1億美元,《星鐵》比《原神》差在哪?

    來源:伯虎財經作者:陳平安即便你沒玩過《原神》,你一定聽說過的它的大名。恨它的人把《原神》開服那天稱作是中國游戲史上最黑暗的一天,有粉絲因為索尼在PS平臺上線《原神》,怒而
  • 消費結構調整丨巨頭低價博弈,拼多多還卷得動嗎?

    來源:征探財經作者:陳香羽隨著流量紅利的退潮,電商的存量博弈越來越明顯。曾經主攻中高端與品質的淘寶天貓、京東重拾&ldquo;低價&rdquo;口號。而過去與他們錯位競爭的拼多多,靠
  • 重估百度丨大模型,能撐起百度的“今天”嗎?

    自象限原創 作者|程心 羅輯2023年之前,對于自己的&ldquo;今天&rdquo;,百度也很迷茫。&ldquo;新業務到 2022 年底還是 0,希望 2023 年出來一個 1。&rdquo;這是2022年底,李彥宏
  • 三星電子Q2營收60萬億韓元 存儲業務營收同比仍下滑超過50%

    7月27日消息,據外媒報道,從三星電子所發布的財報來看,他們主要利潤來源的存儲芯片業務在今年二季度仍不樂觀,營收同比仍在大幅下滑,所在的設備解決方案
Top 主站蜘蛛池模板: 尼勒克县| 会昌县| 广德县| 永兴县| 沂源县| 柳州市| 靖边县| 清远市| 永修县| 鄯善县| 乐业县| 宁晋县| 衡东县| 宜兰县| 彭州市| 青龙| 荔波县| 铁岭市| 八宿县| 康平县| 长岛县| 龙州县| 高唐县| 红河县| 彭阳县| 东乌| 阳西县| 固始县| 九江县| 杭州市| 大洼县| 曲水县| 青神县| 赣州市| 澜沧| 贞丰县| 老河口市| 巍山| 东台市| 射洪县| 西丰县|