HTTP 模块
另一个主要模块名为"http"
。该模块提供了执行 HTTP 服务和产生 HTTP 请求的函数。
启动一个 HTTP 服务器只需要以下代码。
const {createServer} = require("http");
let server = createServer((request, response) => {
response.writeHead(200, {"Content-Type": "text/html"});
response.write(`
<h1>Hello!</h1>
<p>You asked for <code>${request.url}</code></p>`);
response.end();
});
server.listen(8000);
若你在自己的机器上执行该脚本,你可以打开网页浏览器,并访问 http://localhost:8000/hello,就会向你的服务器发出一个请求。服务器会响应一个简单的 HTML 页面。
每次客户端尝试连接服务器时,服务器都会调用传递给createServer
函数的参数。request
和response
绑定都是对象,分别表示输入数据和输出数据。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 客户端。
const {request} = require("http");
let requestStream = request({
hostname: "eloquentjavascript.net",
path: "/20_node.html",
method: "GET",
headers: {Accept: "text/html"}
}, response => {
console.log("Server responded with status code",
response.statusCode);
});
requestStream.end();
request
函数的第一个参数是请求配置,告知 Node 需要访问的服务器、服务器请求地址、使用的方法等信息。第二个参数是响应开始时的回调。该回调会接受一个参数,用于检查相应信息,例如获取状态码。
和在服务器中看到的response
对象一样,request
返回的对象允许我们使用write
方法多次发送数据,并使用end
方法结束发送。本例中并没有使用write
方法,因为 GET 请求的请求正文中无法包含数据。
https
模块中有类似的request
函数,可以用来向https:
URL 发送请求。
但是使用 Node 的原始功能发送请求相当麻烦。 NPM 上有更多方便的包装包。 例如,node-fetch
提供了我们从浏览器得知的,基于Promise
的fetch
接口。