Node HTTP 教程展示了如何使用 HTTP 模块在 JavaScript 中创建 HTTP 服务器和客户端应用程序。
HTTP
HTTP 是一个 Node.js 模块,可用于在 JavaScript 中创建 HTTP 服务器和客户端应用程序。包括 Express 和 HapiJS 在内的流行 JavaScript 框架构建在 HTTP 模块之上。
本教程向您介绍 HTTP 交互的基础知识。要创建真正的 Web 应用程序,我们应该使用完整的 Web 框架,例如 JavaScript 的 Express 或 PHP 的 Symfony。
设置 HTTP
首先,我们安装 HTTP 模块。
$ npm init -y
我们启动一个新的 Node.js 应用程序。
$ npm i http
我们使用npm i http命令安装HTTP。
节点HTTP简单服务器
使用createServer 创建服务器应用程序。
const http = require('http');
http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.write('Hello there');
res.end();
}).listen(8080);
console.log('server running on port 8080');
该示例创建了一个非常简单的 HTTP 服务器,它向客户端发送文本消息。服务器在端口 8080 上运行。
const http = require('http');
首先,我们包含 HTTP 模块。
http.createServer((req, res) => {
我们使用createServer 函数创建一个网络应用程序。它接受一个处理函数,该函数接收两个参数:请求和响应对象。
res.writeHead(200, { 'Content-Type': 'text/plain' });
使用writeHead 方法,我们将标头写入响应。我们指定状态代码和内容类型。
res.write('Hello there');
我们将数据写入响应。
res.end();
我们将响应发送给客户端。
$ node simple.js server running on port 8080
我们启动服务器。
$ curl localhost:8080 Hello there
使用curl 工具,我们向服务器创建一个 GET 请求并接收消息。
节点HTTP发送JSON
在下一个示例中,我们创建一个发送 JSON 响应的服务器。JSON(JavaScript 对象表示法) 是一种轻量级数据交换格式。
const http = require('http');
const server = http.createServer((req, res) => {
if (req.url == '/now') {
res.writeHead(200, { 'Content-Type': 'application/json' });
res.write(JSON.stringify({ now: new Date() }));
res.end();
} else {
res.end('Invalid request');
}
});
server.listen(8080);
console.log('server running on port 8080');
应用程序通过在 JSON 中发送当前日期来响应 /now 请求路径。
if (req.url == '/now') {
我们检查请求 URL 是否等于/now。
res.writeHead(200, { 'Content-Type': 'application/json' });
我们通知客户端我们在标头中发送具有适当内容类型的 JSON 响应。
res.write(JSON.stringify({ now: new Date() }));
我们将 JSON 格式的当前日期写入响应。
节点HTTP发送HTML
接下来,我们将向客户端发送 HTML 数据。
const http = require('http');
const server = http.createServer(function (req, res) {
if (req.url == '/') {
res.writeHead(200, { 'Content-Type': 'text/html' });
res.write('<html><body><p>This is home page.</p></body></html>');
res.end();
} else if (req.url == "/contact") {
res.writeHead(200, { 'Content-Type': 'text/html' });
res.write('<html><body><p>This is contact page</p></body></html>');
res.end();
} else if (req.url == "/admin") {
res.writeHead(200, { 'Content-Type': 'text/html' });
res.write('<html><body><p>This is admin page</p></body></html>');
res.end();
} else {
res.end('Invalid request');
}
});
server.listen(8080);
console.log('server running on port 8080');
我们指定 text/html 内容类型并将 HTML 标记写入响应。
节点HTTP查询参数
客户端可以通过向 URL 添加查询参数来与服务器通信。
const http = require('http');
const url = require('url');
http.createServer((req, res) => {
let q = url.parse(req.url, true).query;
let msg = `${q.name} is ${q.age} years old`;
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.write(msg);
res.end();
}).listen(8080);
console.log('server running on port 8080');
在示例中,服务器使用根据查询参数构建的消息进行响应。
const url = require('url');
为了解析查询参数,我们使用url模块。
let q = url.parse(req.url, true).query;
我们得到具有值的查询对象。
let msg = `${q.name} is ${q.age} years old`;
我们根据查询参数构建消息。
$ curl "localhost:8080/?name=Peter&age=34" Peter is 34 years old
启动服务器后,我们使用curl创建请求。我们指定查询参数。
节点 HTTP 服务器
以下示例创建了一个更复杂的 HTTP 服务器。 docs 子目录中有三个 HTML 文件。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>About page</title>
</head>
<body>
<p>This is about page.</p>
</body>
</html>
这是about.html文件。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Contact page</title>
</head>
<body>
<p>This is contact page.</p>
</body>
</html>
这是contact.html文件。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Home page</title>
</head>
<body>
<p>
This is home page.
</p>
</body>
</html>
这是index.html文件。
const http = require('http');
const fs = require('fs');
const url = require('url');
const server = http.createServer((req, res) => {
let pathname = url.parse(req.url).pathname;
console.log(`Request for ${pathname} received`);
if (pathname == '/') {
pathname = '/index.html';
}
fs.readFile('docs/' + pathname.substr(1), (err, data) => {
if (err) {
console.error(err);
res.writeHead(404, { 'Content-Type': 'text/plain' });
res.write('404 - file not found');
} else {
res.writeHead(200, { 'Content-Type': 'text/html' });
res.write(data.toString());
}
res.end();
});
});
server.listen(8080);
console.log('server running on port 8080');
const fs = require('fs');
我们使用fs模块来读取HTML文件。
该示例从文件系统读取 HTML 文件。
let pathname = url.parse(req.url).pathname;
我们确定路径名,也就是要加载的文件名。
if (pathname == '/') {
pathname = '/index.html';
}
对于根页面,我们发送index.html。
fs.readFile('docs/' + pathname.substr(1), (err, data) => {
使用readFile方法,我们读取HTML文件的内容。
if (err) {
console.error(err);
res.writeHead(404, { 'Content-Type': 'text/plain' });
res.write('404 - file not found');
} ...
如果出现错误,我们会向客户端发送 404 代码。
} else {
res.writeHead(200, { 'Content-Type': 'text/html' });
res.write(data.toString());
}
如果找到并读取了文件,我们将文件的内容发送给客户端。
节点 HTTP GET 请求
我们也可以使用 HTTP 模块来创建客户端请求。
const http = require('http');
const options = {
hostname: 'webcode.me',
port: 80,
path: '/',
method: 'GET'
};
const req = http.request(options, (res) => {
console.log(`statusCode: ${res.statusCode}`);
res.on('data', (d) => {
process.stdout.write(d);
});
});
req.on('error', (err) => {
console.error(err);
});
req.end();
该示例创建了对 webcode.me 的 HTTP GET 请求。
const options = {
hostname: 'webcode.me',
port: 80,
path: '/',
method: 'GET'
};
选项包含生成的请求的主机名、端口、路径和 HTTP 方法。
const req = http.request(options, (res) => {
使用request 生成请求。
res.on('data', (d) => {
process.stdout.write(d);
});
我们不断地将传入数据写入数据事件处理程序中的控制台。
$ node http_get.js
statusCode: 200
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My html page</title>
</head>
<body>
<p>
Today is a beautiful day. We go swimming and fishing.
</p>
<p>
Hello there. How are you?
</p>
</body>
</html>
或者,我们可以使用get 方法。
const http = require('http')
const req = http.get({ host: 'webcode.me', path: '/' }, (res) => {
// Continuously update stream with data
let content = '';
res.on('data', (chunk) => {
content += chunk;
});
res.on('end', () => {
console.log(content);
});
});
req.end();
我们向同一网站生成 GET 请求。
// Continuously update stream with data
let content = '';
res.on('data', (chunk) => {
content += chunk;
});
我们不断地将检索到的数据块添加到content 变量。
res.on('end', () => {
console.log(content);
});
最后,我们将变量打印到控制台。
节点 HTTP POST 请求
以下示例创建了对httpbin.orgwebsite 的 POST 请求。这是一个免费站点,我们可以在其中测试我们的请求。由于该站点使用 HTTPS 协议,因此我们使用 https 模块。
const https = require('https');
let payload = JSON.stringify({
"name": "Peter",
"age": 34
});
let headers = {
'Content-Type': 'application/json',
'Content-Length': Buffer.byteLength(payload, 'utf8')
};
let options = {
host: 'httpbin.org',
port: 443,
path: '/post',
method: 'POST',
headers: headers
};
let reqPost = https.request(options, (res) => {
console.log("status code: ", res.statusCode);
res.on('data', (chunks) => {
process.stdout.write(chunks);
});
});
reqPost.write(payload);
reqPost.end();
reqPost.on('error', (err) => {
console.error(err);
});
该示例将数据发送到测试网站。服务器响应数据,其中包括我们发送的有效载荷。
const https = require('https');
我们使用https模块。
payload = JSON.stringify({
"name": "Peter",
"age": 34
});
这是要发送的负载。
let headers = {
'Content-Type': 'application/json',
'Content-Length': Buffer.byteLength(payload, 'utf8')
};
这些是标题。我们发送 JSON 数据。我们指定内容长度。
let options = {
host: 'httpbin.org',
port: 443,
path: '/post',
method: 'POST',
headers: headers
};
这些是 POST 请求的选项。 HTTPS 标准端口为 443。
let reqPost = https.request(options, (res) => {
console.log("status code: ", res.statusCode);
res.on('data', (chunks) => {
process.stdout.write(chunks);
});
});
在 post 调用的数据事件处理程序中,我们将数据写入控制台。
reqPost.write(payload);
我们将负载数据写入 POST 请求。
reqPost.end();
请求已发送。
在本文中,我们使用了 JavaScript HTTP 模块。
列出 JavaScript 教程。
