ZetCode

Node HTTP 教程

最后修改于 2023 年 10 月 18 日

在本文中,我们将展示如何使用 HTTP 模块在 JavaScript 中创建 HTTP 服务器和客户端应用程序。

HTTP

HTTP 是一个 Node.js 模块,可用于在 JavaScript 中创建 HTTP 服务器和客户端应用程序。流行的 JavaScript 框架,包括 Express 和 HapiJS,都是基于 HTTP 模块构建的。

本教程教你 HTTP 交互的基础知识。要创建真正的 Web 应用程序,我们应该使用一个完整的 Web 框架,例如 JavaScript 的 Express 或 PHP 的 Symfony。

设置 HTTP

首先,我们安装 HTTP 模块。

$ npm init -y

我们启动一个新的 Node.js 应用程序。

$ npm i http

我们使用 npm i http 命令安装 HTTP。

Node HTTP 简单服务器

使用 createServer 创建服务器应用程序。

simple.js
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 函数创建 Web 应用程序。它接受一个处理程序函数,该函数接收两个参数:请求和响应对象。

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 请求并接收消息。

Node HTTP 发送 JSON

在下一个示例中,我们创建一个发送 JSON 响应的服务器。 JSON (JavaScript Object Notation) 是一种轻量级的数据交换格式。

send_json.js
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 格式的当前日期写入响应。

Node HTTP 发送 HTML

接下来,我们将向客户端发送 HTML 数据。

send_html.js
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 标签写入响应。

注意: 在实际应用程序中,我们不会将 HTML 代码写入响应。我们使用模板。

Node HTTP 查询参数

客户端可以通过将查询参数添加到 URL 来与服务器通信。

query_params.js
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 创建一个请求。我们指定查询参数。

Node HTTP 服务器

以下示例创建一个更复杂的 HTTP 服务器。我们在 docs 子目录中有三个 HTML 文件。

docs/about.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 文件。

docs/contact.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 文件。

docs/index.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 文件。

http_server.js
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());
}

如果找到并读取了文件,我们向客户端发送文件的内容。

Node HTTP GET 请求

我们也可以使用 HTTP 模块创建客户端请求。

http_get.js
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 方法。

http_get.js
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);
});

最后,我们将该变量打印到控制台。

Node HTTP POST 请求

以下示例创建一个到 httpbin.org 网站的 POST 请求。这是一个免费的网站,我们可以在其中测试我们的请求。由于该网站使用 HTTPS 协议,我们使用 https 模块。

http_post.js
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();

请求已发送。

来源

JS HTTP 模块

在本文中,我们使用了 JavaScript HTTP 模块。

作者

我的名字是 Jan Bodnar,我是一个充满激情的程序员,拥有丰富的编程经验。自 2007 年以来,我一直在撰写编程文章。到目前为止,我已经撰写了 1,400 多篇文章和 8 本电子书。我拥有超过十年的编程教学经验。

查看 所有 JavaScript 教程。