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 names | Packet size | API style | Introduction |
---|---|---|---|
node-fetch | 0.4kb | promise / stream | A light-weight module that brings window.fetch to Node.js |
got | 48.4kb | promise / stream | Simplified HTTP requests |
axios | 11.9kb | promise / stream | Promise based HTTP client for the browser and node.js |
superagent | 18kb | chaining / promise | Small progressive client-side HTTP request library, and Node.js module with the same API, sporting many high-level HTTP client features |
urllib | 816kb | callback / promise | Help 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 withfetch
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
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。