HTTP 模块

另一个主要模块名为"http"。该模块提供了执行 HTTP 服务和产生 HTTP 请求的函数。

启动一个 HTTP 服务器只需要以下代码。

  1. const {createServer} = require("http");
  2. let server = createServer((request, response) => {
  3. response.writeHead(200, {"Content-Type": "text/html"});
  4. response.write(`
  5. <h1>Hello!</h1>
  6. <p>You asked for <code>${request.url}</code></p>`);
  7. response.end();
  8. });
  9. server.listen(8000);

若你在自己的机器上执行该脚本,你可以打开网页浏览器,并访问 http://localhost:8000/hello,就会向你的服务器发出一个请求。服务器会响应一个简单的 HTML 页面。

每次客户端尝试连接服务器时,服务器都会调用传递给createServer函数的参数。requestresponse绑定都是对象,分别表示输入数据和输出数据。request包含请求信息,例如该对象的url属性表示请求的 URL。

因此,当你在浏览器中打开该页面时,它会向你自己的计算机发送请求。 这会导致服务器函数运行并返回一个响应,你可以在浏览器中看到该响应。

你需要调用response对象的方法以将一些数据发回客户端。第一个函数调用(writeHead)会输出响应头(参见第十七章)。你需要向该函数传递状态码(本例中 200 表示成功)和一个对象,该对象包含协议头信息的值。该示例设置了"Content-Type"头,通知客户端我们将发送一个 HTML 文档。

接下来使用response.write来发送响应体(文档自身)。若你想一段一段地发送相应信息,可以多次调用该方法,例如将数据发送到客户端。最后调用response.end发送相应结束信号。

调用server.listen会使服务器在 8000 端口上开始等待请求。这就是你需要连接localhost:8000和服务器通信,而不是localhost(这样将会使用默认端口,即 80)的原因。

当你运行这个脚本时,这个进程就在那里等着。 当一个脚本正在监听事件时 - 这里是网络连接 - Node 不会在到达脚本末尾时自动退出。为了关闭它,请按Ctrl-C

一个真实的 Web 服务器需要做的事情比示例多得多。其差别在于我们需要根据请求的方法(method属性),来判断客户端尝试执行的动作,并根据请求的 URL 来找出动作处理的资源。本章随后会介绍更高级的服务器。

我们可以使用http模块的request函数来充当一个 HTTP 客户端。

  1. const {request} = require("http");
  2. let requestStream = request({
  3. hostname: "eloquentjavascript.net",
  4. path: "/20_node.html",
  5. method: "GET",
  6. headers: {Accept: "text/html"}
  7. }, response => {
  8. console.log("Server responded with status code",
  9. response.statusCode);
  10. });
  11. requestStream.end();

request函数的第一个参数是请求配置,告知 Node 需要访问的服务器、服务器请求地址、使用的方法等信息。第二个参数是响应开始时的回调。该回调会接受一个参数,用于检查相应信息,例如获取状态码。

和在服务器中看到的response对象一样,request返回的对象允许我们使用write方法多次发送数据,并使用end方法结束发送。本例中并没有使用write方法,因为 GET 请求的请求正文中无法包含数据。

https模块中有类似的request函数,可以用来向https: URL 发送请求。

但是使用 Node 的原始功能发送请求相当麻烦。 NPM 上有更多方便的包装包。 例如,node-fetch提供了我们从浏览器得知的,基于Promisefetch接口。