Node.js 中最常用的内置模块之一,许多第三方的网络库都是基于它封装的,

http / https 模块可用于创建 HTTP 服务器,也可用于向已有服务发起请求并获取响应。

下面将分别介绍发起请求和创建 web 服务器两种用法。

1 发起请求

这里默认你了解基本的 HTTP 协议相关知识 (不熟悉的同学可以阅读 MDN:HTTP 介绍)。

1.1 http.get

用于快速发起 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) }) }) ```

1.2 http.request

前面只介绍了 http.get 发起 GET 请求,

当然也支持其它请求方式 (POSTPUTDELETE 等等),均通过 http.request 触发。

先复现一次前面的 http.get

```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

下面分别介绍一下简单用法。

1.3 fetch 和 axios

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) }) ```

2 创建 HTTP Service

利用 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('

Hello, World!

') }) server.listen(4275, () => { console.log('Server running at http://127.0.0.1:4275/') }) ```

运行

js node server.mjs

使用浏览器访问 http://127.0.0.1:4275 即可看到结果。

接下来咱们进一步了解一下 requestresponse 相关属性。

3 request 内容介绍

类型定义是 http.IncomingMessage

可以从中获取从客户端传递的一些信息,下面介绍一些常用的。

3.1 请求路径和方法

可以获取请求方法请求 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' })

接下来介绍一下客户端通常传递数据的几种方式。

3.2 query 参数解析

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 )

效果如下。

3.3 body 参数解析

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 }) })

通过监听 dataend 事件获取。

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) })

运行结果如下。

3.4 headers 参数

另外一种就是通过请求头传递参数了。

通过 req.headers 获取。

js console.log('headers', req.headers)

4 response 内容介绍

类型定义是 http.ServerResponse

通常用于设置向客户端要返回的内容信息。

js // 设置响应状态码为 200 res.statusCode = 200; // 设置响应头,指定响应内容类型为 text/html res.setHeader('Content-Type', 'text/html'); // 发送响应内容到客户端,结束响应 res.end('<h1>Hello, World!</h1>');

如果通过 curl 发起请求调用,添加 -i 参数即可获取到这些内容。

4.1 设置响应状态码

通过 res.statusCode 设置响应的状态码。

① 正常情况下,默认 200

js res.statusCode = 200

② 资源不存在 404

js res.statusCode = 404

③ 运行发现错误 500

js res.statusCode = 500

4.2 设置响应头

通过 res.setHeader 设置要向客户端返回额头信息。

js res.setHeader('Content-Type', 'text/html')

Content-Type 通常用于描述要传递的数据类型。

比如如果是 JSON 就是。

js res.setHeader('Content-Type', 'application/json')

4.3 设置响应的内容

可以通过 res.writeres.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 个当下最流行的发起网络请求的 库/方法 axiosfetch 的基本用法。

接着介绍了如何创建一个简单的 Web服务器,可以看出来利用 Node.js 可以非常简单的创建 HTTP Service,对于一些简单场景可以不依赖第三方库,实现快速的代码编写实现。

最后介绍了 http.requesthttp.response 对象上常用的方法和属性的获取方式: