使用 Node 构建 HTTP 服务器的最简单方法
在了解 ExpressJS 的存在之前,我们必须先了解一下没有它该怎么办。使用 ExpressJS 最基本的事情就是搭建一个服务器。让我们借助 NodeJS 来实现这一点。
我们需要构建一个能够简单地从外部 API 获取数据并处理基本 HTTP 请求的程序。
基本 HTTP 服务器
以下是简单 Web 服务器的示例:
const HTTP = require('http');
const port = process.env.PORT || 3000
const server = HTTP.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/html');
res.end('<h1>Joey doesnt share food!</h1>');
});
server.listen(port, () => console.log(
`Server running on port ${port}`
));
首先,我们在文件 **index.js* 中包含 HTTP 核心模块。*值得注意的是,我们没有使用较新的 ES6 导入语法来包含核心模块。这是因为 Node 尚未完全采用 ES6。此外,我们定义了一个变量port,设置为process.env.PORT || 3000。当您在其他服务(如 Heroku 和 AWS)上托管应用程序时,您的主机可能会为您独立配置 process.env.PORT 变量。毕竟,您的脚本在他们的环境中运行。您也可以将其硬编码到特定端口,例如8080。
因此 process.env.PORT || 3000 表示:环境变量 port 中的内容,如果 port 中没有内容,则为 3000。此外,我们使用createServer函数创建一个服务器。它接受一个回调函数。
我们传递的回调函数会在每次收到请求时执行。一旦收到请求,就会调用 request 事件,并提供两个对象:一个请求对象和一个响应对象。
-
Request提供了请求的详细信息。通过它,我们可以访问请求头和请求数据。
-
响应用于包含我们要返回给客户端的数据。
使用res.statusCode = 200表示响应成功。我们还设置了 Content-Type 标头。标头由setHeader
函数 定义,该函数以键值对的形式接收两个参数。
res.setHeader('Content-Type', 'text/html')
我们使用以下方式关闭已发送的响应:
res.end('<h1>Joey doesnt share food!</h1>')
服务器被设置为监听port变量指定的端口。当服务器准备就绪时,将调用 listen 回调函数。
是啊!我知道。还不错。
不幸的是,当我们尝试添加一些通用功能时,这个设置变得很混乱。让我们看看结果如何。
HTTP 'GET' 请求
首先,我们创建一个名为index.js的文件。使用此文件,我们创建一个服务器,用于从免费的Cat Facts API 中检索数据。此 API 以 JSON 格式返回请求的数据。此 API 支持https请求,这大致相当于http的加密版本。因此,我们首先在文件中添加核心模块https 。
//index.js
const HTTPS = require('https');
我们现在需要的是从上述 API 中检索数据。因此,我们在https上调用get()方法。 此方法接受两个参数:
- API URL
- 处理 API 发送的响应的函数
// index.js
const HTTPS = require('https')
HTTPS
.get( 'https://catfact.ninja/fact', res => {
})
接下来,我们监听响应对象中的on('data', () => {})
和on('end', () => {})
事件。'on data' 事件负责监听并收集请求执行时返回的数据。为了实现这一点,我们声明了一个名为 data 的变量,并将其初始值设置为空字符串。然后,我们开始将数据流中的小段连接到 data 字符串中。
// index.js
const HTTPS = require('https')
HTTPS
.get( 'https://catfact.ninja/fact', res => {
let data = ''
res.on( 'data', bits => data += bits )
})
后面跟着“on end”。可以看到,我们这里获取的数据是 JSON 格式的。我们需要将其转换为 JavaScript 对象才能对其进行操作。因此,我们对数据调用 JSON.parse() 函数,将其从 JSON 转换为 JavaScript 对象。
// index.js
const HTTPS = require('https')
HTTPS
.get( 'https://catfact.ninja/fact', res => {
let data = ''
res.on('data', bits => data += bits )
res.on( 'end' , () => {
let parsedData = JSON.parse(data)
console.log(parsedData)
})
})
在终端中运行 node index.js后,你会看到类似的内容:
为了捕获请求过程中可能无意引发的任何错误,我们会监听错误。在 get() 函数的末尾,我们添加了一个on error事件,并在 console.log 中记录错误。
// index.js
const HTTPS = require('https')
HTTPS
.get( 'https://catfact.ninja/fact', res => {
let data = ''
res.on('data', bits => data += bits )
res.on( 'end' , () => {
let parsedData = JSON.parse(data)
console.log(parsedData)
})
})
.on('error', err => {
console.log("Error: ", err.message)
})
太棒了!我们终于向公共 API(Cat API)发出了请求,并成功在终端中记录了响应。至此,我们已经学习了如何创建服务器并处理GET请求。让我们继续学习,将目前学到的知识结合起来。
Node.js 服务器渲染GET请求的结果
我们将通过一个简单的 HTTP 服务器来渲染最终解析的数据。在这里,我们构建一个简单的服务器,并以我们之前学到的方式将数据输入到服务器中。我们使用http核心模块来构建服务器。由于let和const关键字声明了一个块作用域变量,因此我们需要在定义parsedData变量的地方创建服务器。因此,我们在定义服务器变量的地方调用listen方法。如前所述,我们将状态码设置为200,表示响应成功,并将 Header 设置为text/html,以便以文本或 HTML 格式接收响应。此外,我们还允许来自所有来源的访问,以避免出现 CORS 错误。CORS错误是另一个完全不同的话题。
//index.js
const HTTPS = require('https');
const HTTP = require('http');
const port = process.env.PORT || 3000
HTTPS
.get( 'https://catfact.ninja/fact', res => {
let data = ''
res.on('data', chunks => data += chunks )
res.on( 'end' , () => {
let parsedData = JSON.parse(data)
console.log(parsedData)
const server = HTTP.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/html');
res.setHeader('Access-Control-Allow-Origin', '*')
res.end(parsedData.fact);
})
server.listen(port, () => console.log(
`Server running on port ${port}`
));
})
})
.on('error', err => {
console.log("Error: ", err.message)
})
parsedData对象实际返回两个值:fact和length。但我们只需要 fact,因此将parsedData.fact传递给res.end() 。如果我们将Content-Type标头设置为application/json,则必须将parsedData对象转换回 JSON 格式。在这种情况下,通常使用 JSON.stringify() 将对象转换为 JSON。
我们的服务器现在可以启动了!我们在终端中使用node index.js启动服务器,并观察到类似下图的内容: