Node.js 中最常用的内置模块之一,许多第三方的网络库都是基于它封装的,
http / https 模块可用于创建 HTTP 服务器,也可用于向已有服务发起请求并获取响应。
下面将分别介绍发起请求和创建 web 服务器两种用法。
这里默认你了解基本的 HTTP 协议相关知识 (不熟悉的同学可以阅读 MDN:HTTP 介绍)。
用于快速发起 GET
请求,下面是个例子,拉取掘金的文章榜单。
```js // import http from 'http' import https from 'https' // 由于请求的目标资源是 https 协议,所以这里使用 https 模块 https.get( 'https://api.juejin.cn/content_api/v1/content/article_rank?category_id=1&type=hot&count=3&from=1&aid=2608&uuid=7145810834685003271&spider=0', (res) => { // 响应内容拼接 let content = '' res.on('data', (chunk) => { content += chunk })
// 读完对外暴露内容和状态码
res.on('end', () => {
console.log(content)
})
res.on('error', (err) => {
console.log(err)
})
} ) ```
结果如下,JSON 格式的字符串,
当然也支持传递额外的参数 (下面介绍另一种写法)。
```js const req = https.get( 'https://api.juejin.cn/content_api/v1/content/article_rank?category_id=1&type=hot&count=3&from=1&aid=2608&uuid=7145810834685003271&spider=0', { headers: { 'Content-Type': 'application/json' } } )
req.on('response', (res) => { // 响应内容拼接 let content = '' res.on('data', (chunk) => { content += chunk })
res.on('end', () => { console.log(content) })
res.on('error', (err) => { console.log(err) }) }) ```
前面只介绍了 http.get
发起 GET 请求,
当然也支持其它请求方式 (POST
、PUT
、DELETE
等等),均通过 http.request
触发。
先复现一次前面的 http.get
:
域名
,方法
,端口
,资源路径
,查询参数
等;URL
方法,直接解析完整的一个 url 链接。```js import https from 'https'
const url = new URL( 'https://api.juejin.cn/content_api/v1/content/article_rank?category_id=1&type=hot&count=3&from=1&aid=2608&uuid=7145810834685003271&spider=0' ) console.log(url) const req = https.request( { // 设置请求方法 method: 'GET', // http 80 https 443 port: 443, hostname: url.hostname, path: url.pathname + url.search }, (res) => { let content = '' res.on('data', (chunk) => { content += chunk }) res.on('end', () => { console.log('statusCode', res.statusCode) console.log(content) }) } ) // 发送请求 req.end() ```
下面是个发起 POST 请求的例子。
```js import https from 'https'
const url = new URL( 'https://api.juejin.cn/content_api/v1/content/article_rank?category_id=1&type=hot&count=3&from=1&aid=2608&uuid=7145810834685003271&spider=0' )
// POST const req = https.request( { // 设置请求方法 method: 'POST', // http 80 https 443 port: 443, hostname: url.hostname, path: url.pathname + url.search, headers: { 'Content-Type': 'application/json' } }, (res) => { let content = '' res.on('data', (chunk) => { content += chunk }) res.on('end', () => { console.log('statusCode', res.statusCode) console.log(content) }) } ) // req.write('请求实体') req.write(JSON.stringify({ name: 'xm' })) req.end() ```
运行结果如下,
因为这个资源实际不存在所以返回了 404
。
如果之前熟悉 WEB (浏览器) 的中的开发,会感觉这里的回调处理会非常的奇怪,有些别扭。
当然 Node.js 里面也可以使用 axios,同时 Node 里也支持 fetch
。
下面分别介绍一下简单用法。
Node.js 在 18 开始默认开启 fetch 支持。
下面是 fetch 发起 GET 请求例子 (更多用法参考 fetch 文档)。
js
fetch(
'https://api.juejin.cn/content_api/v1/content/article_rank?category_id=1&type=hot&count=3&from=1&aid=2608&uuid=7145810834685003271&spider=0'
)
.then((res) => res.json())
.then((data) => {
console.log(data)
})
.catch((err) => {
console.error(err)
})
使用第三方模块 axios 介绍。
```sh
npm i axios ```
使用示例。
```js import axios from 'axios'
axios .get( 'https://api.juejin.cn/content_api/v1/content/article_rank?category_id=1&type=hot&count=3&from=1&aid=2608&uuid=7145810834685003271&spider=0' ) .then((res) => { console.log(res.data) }) .catch((err) => { console.error(err) }) ```
利用 http.createServer
即可创建一个简单的 Web 服务。
```js import http from 'http'
const server = http.createServer((req, res) => { res.statusCode = 200 res.setHeader('Content-Type', 'text/html') res.end('
运行
js
node server.mjs
使用浏览器访问 http://127.0.0.1:4275
即可看到结果。
接下来咱们进一步了解一下 request
和 response
相关属性。
类型定义是 http.IncomingMessage。
可以从中获取从客户端传递的一些信息,下面介绍一些常用的。
可以获取请求方法请求 url
。
js
// 在之前代码的基础上做一点微调
// server-req.mjs
http.createServer((req, res) => {
// 获取请求的路径和方法
const { url, method } = req
console.log(method, url)
// 省略其它代码...
})
启动后我们可以通过 curl
或者 浏览器/Node.js
里 fetch 调用。
下面启动后实操一下。
截图里是 curl
发起请求,下面是浏览器和 Node.js 使用 fetch
发起请求示例。
js
fetch('http://127.0.0.1:4275?hello=world', {
method: 'POST'
})
接下来介绍一下客户端通常传递数据的几种方式。
GET
请求通常会通过 query 传递一些参数,形式如下。
/a/b/c?name=123
/a/b/c?name=123&age18
/a/b/c?name=123&age18&id=666
可以直接使用 URL
模块的 searchParams
直接提取。
js
const { url, method } = req
const query = Object.fromEntries(
new URL(url, 'http://localhost').searchParams
)
效果如下。
POST
请求通常会通过 body
传递数据。
js
fetch('http://127.0.0.1:4275?hello=world', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: 'xm',
age: 18
})
})
通过监听 data
和 end
事件获取。
js
let body = []
req
.on('data', (chunk) => {
body.push(chunk)
})
.on('end', () => {
body = Buffer.concat(body).toString()
body = JSON.parse(body)
console.log('body', body)
})
运行结果如下。
另外一种就是通过请求头传递参数了。
通过 req.headers
获取。
js
console.log('headers', req.headers)
类型定义是 http.ServerResponse。
通常用于设置向客户端要返回的内容信息。
js
// 设置响应状态码为 200
res.statusCode = 200;
// 设置响应头,指定响应内容类型为 text/html
res.setHeader('Content-Type', 'text/html');
// 发送响应内容到客户端,结束响应
res.end('<h1>Hello, World!</h1>');
如果通过 curl
发起请求调用,添加 -i
参数即可获取到这些内容。
通过 res.statusCode
设置响应的状态码。
① 正常情况下,默认 200
js
res.statusCode = 200
② 资源不存在 404
js
res.statusCode = 404
③ 运行发现错误 500
js
res.statusCode = 500
通过 res.setHeader
设置要向客户端返回额头信息。
js
res.setHeader('Content-Type', 'text/html')
Content-Type
通常用于描述要传递的数据类型。
比如如果是 JSON
就是。
js
res.setHeader('Content-Type', 'application/json')
可以通过 res.write
和 res.end
设置,
终止并返回内容。
js
res.end('<h1>Node.js</h1>')
多次返回内容再调用结束。
js
res.write('<h1>')
res.write('Node.js')
res.write('o')
res.write('</h1>')
res.end()
本节主要介绍了如何利用 http
模块的 发起HTTP请求
和 创建Web服务器
两项能力。
在介绍发起请求部分,同时介绍了另外 2 个当下最流行的发起网络请求的 库/方法
axios 和 fetch 的基本用法。
接着介绍了如何创建一个简单的 Web服务器
,可以看出来利用 Node.js 可以非常简单的创建 HTTP Service,对于一些简单场景可以不依赖第三方库,实现快速的代码编写实现。
最后介绍了 http.request
和 http.response
对象上常用的方法和属性的获取方式:
url
(请求路径)、method
(请求方法)、headers
(请求头部)、body
(请求体)、query
(url 携带查询参数);statusCode
(响应状态码)、setHeader
(设置响应头)、write/end
(设置响应内容)。