2

Preface

In the browser, if we want to initiate a request, we will use xhr , but this kind of underlying api is often called in a relatively simple way. In order to improve development efficiency, jQuery's $.ajax may be the best choice. Fortunately, a more modern fetch api appeared later.

But considering fetch , and it does not support some global configuration, and request interruption, in actual use, we may use the axios request library to make some requests. In Node.js, almost all requests are made through the library request Unfortunately, request stopped maintenance two years ago. It is not easy to find an alternative library in Node.js.

In the issues of request, there is a table recommending some common request libraries in Node.js:

Package namesPacket sizeAPI styleIntroduction
node-fetch0.4kbpromise / streamA light-weight module that brings window.fetch to Node.js
got48.4kbpromise / streamSimplified HTTP requests
axios11.9kbpromise / streamPromise based HTTP client for the browser and node.js
superagent18kbchaining / promiseSmall progressive client-side HTTP request library, and Node.js module with the same API, sporting many high-level HTTP client features
urllib816kbcallback / promiseHelp in opening URLs (mostly HTTP) in a complex world — basic and digest authentication, redirections, cookies and more.

axios , which is frequently used in browsers, is not easy to use in Node.js, especially when uploading files, there will be many unexpected problems.

Recently, when I was online 🏄🏿, I found that Node.js officially has a request library: undici . The name acquisition is quite complicated. So, today’s article will introduce undici . Incidentally, undici is Italian 11 mean, like two-eleven is coming, good Maotai 🤔.

Undici means eleven in Italian. 1.1 -> 11 -> Eleven -> Undici. It is also a Stranger Things reference.

Get started

We can directly through npm to install undici :

npm install undici -S

undici exposes an object, which provides several APIs below:

  • undici.fetch : Initiate a request, which is consistent with fetch
  • undici.request : initiate a request, request library, this method supports Promise;
  • undici.stream : Process file stream, which can be used to download files;

undici.fetch

Note: This method requires node version>= v16.5.0

Before undici.fetch , you need to start a simple login service koa

const Koa = require('koa')
const bodyParser = require('koa-bodyparser')

const app = new Koa()

app.use(bodyParser())
app.use(ctx => {
  const { url, method, body } = ctx.request
  if (url === '/login') {
    if (method === 'POST') {
      if (body.account === 'shenfq' && body.password === '123456') {
        ctx.body = JSON.stringify({
          name: 'shenfq',
          mobile: '130xxxxxx'
        })
        return
      }
    }
  }
  ctx.status = 404
  ctx.body = JSON.stringify({})
})

app.listen(3100)

The above code is very simple, and only supports accepting a POST to /login . Next, use undici.fetch initiate a POST request.

const { fetch } = require('undici')

const bootstrap = async () => {
  const api = 'http://localhost:3100/login'
  const rsp = await fetch(api, {
    method: 'POST',
    headers: {
      'content-type': 'application/json'
    },
    body: JSON.stringify({
      account: 'shenfq',
      password: '123456'
    })
  })
  if (rsp.status !== 200) {
    console.log(rsp.status, '请求失败')
    return
  }
  const json = await rsp.json()
  console.log(rsp.status, json)
}

bootstrap()

If you change the request method to GET , 404 will be returned.

const rsp = await fetch(api, {
  method: 'GET'
})

undici.request

undici.request invocation and undici.fetch similar mass participation forms are also similar.

const { request } = require('undici')

const bootstrap = async () => {
  const api = 'http://localhost:3100/login'
  const { body, statusCode } = await request(api, {
    method: 'POST',
    headers: {
      'content-type': 'application/json'
    },
    body: JSON.stringify({
      account: 'shenfq',
      password: '123456'
    })
  })
  const json = await body.json()
  console.log(statusCode, json)
}

bootstrap()

Only the returned result is a bit different. The http response result returned by the request body attribute, and this attribute also supports fetch such as .json() / .text() similar to 0616f7f3c74dd2.

Interrupt request

Install the abort-controller library, then instantiate abort-controller , and pass the interrupt signal to the request configuration.

npm i abort-controller
const undici = require('undici')
const AbortController = require('abort-controller')

// 实例化 abort-controller
const abortController = new AbortController()
undici.request('http://127.0.0.1:3100', {
  method: 'GET',
  // 传入中断信号量
  signal: abortController.signal,
}).then(({ statusCode, body }) => {
  body.on('data', (data) => {
    console.log(statusCode, data.toString())
  })
})

We ran the code and found that it was possible to request success because we did not actively call the interrupt method.

undici.request('http://127.0.0.1:3100', {
  method: 'GET',
  signal: abortController.signal,
}).then(({ statusCode, body }) => {
  console.log('请求成功')
  body.on('data', (data) => {
    console.log(statusCode, data.toString())
  })
}).catch(error => {
  // 捕获由于中断触发的错误
  console.log('error', error.name)
})

// 调用中断
abortController.abort()

Now running the code will find that the request success log is catch logic is entered, and the requested interruption is successfully performed.

undici.steam

undici.steam method can be used to download files or interface agents.

Download Document

const fs = require('fs')const { stream } = require('undici')const out = fs.createWriteStream('./宋代-哥窑-金丝铁线.jpg')const url = 'https://img.dpm.org.cn/Uploads/Picture/dc/cegift/cegift6389.jpg'stream(url, { opaque: out }, ({ opaque }) => opaque)

Interface proxy

const http = require('http')const undici = require('undici')// 将 3100 端口的请求,代理到 80 端口const client = new undici.Client('http://localhost')http.createServer((req, res) => {  const { url, method } = req  client.stream(    { method, path: url,opaque: res },    ({ opaque }) => opaque  )}).listen(3100)

Summarize

This article only introduces how to undici undici . It seems that 0616f7f3c7508c is relatively low to get started. But compatibility is not fetch . For example, 0616f7f3c7508d only supports node@v16.5.0 above 0616f7f3c7508f.

For this relatively new library, I personally suggest to wait and see for a while. Although request has been abandoned, we still use some libraries that have been tested for a long time. For example, the urllib used in the egg framework, and a node-fetch , is it relatively low to get started, consistent with the use fetch


Shenfq
4k 声望6.8k 粉丝