http 模块
http
模块用于 HTTP 通信。
http.Server
http.Server
属性指向一个类,表示 Web 服务器实例。
这个类继承了net.Server
,而net.Server
继承了 EventEmitter 接口,因此可以使用server.on()
方法监听事情。最重要的一个事件是request
,表示收到 HTTP 请求。
server.on('request', (request, response) => { response.end('Hello, world!');});
server.listen()
方法用于启动 Web 服务。这个方法需要指定监听的端口,以及一个回调函数(启动后要做什么)。
server.listen(PORT, () => { console.log(`starting server at port ${PORT}`);});
http.createServer()
http.createServer()
方法用于创建一个 Web 服务器,它的返回值就是一个http.Server
实例。
const { createServer } = require('http');
// 指定端口const PORT = process.env.PORT || 8080;const server = createServer();
server.on('request', (request, response) => { response.end('Hello, world!');});
server.listen(PORT, () => { console.log(`starting server at port ${PORT}`);});
request
事件的回调函数,可以作为createServer()
方法的参数。因此,上面的代码也可以写成下面的样子。
const { createServer } = require('http');
const PORT = process.env.PORT || 8080;
const server = createServer((request, response) => { response.end('Hello, world!');}).listen(PORT, () => { console.log(`starting server at port ${PORT}`);});
response 对象
HTTP 请求和回应都是数据流(stream),request
是只读数据流,response
是可写数据流。
response.write()
方法表示依次向 HTTP 回应写入内容。
response.end()
方法表示写入数据以后,关闭response
数据流。
const { createServer } = require('http');
createServer((request, response) => { // 等同于 response.end('Hello, world!') response.write('Hello'); response.write(', '); response.write('World!'); response.end();}).listen(8080);
注意,response.end()
是必需的,而且必须写在最后,否则 Node 不会关闭请求。
如果要向客户端发送文件,也可以写成数据流。
const { createReadStream } = require('fs');const { createServer } = require('http');
createServer((request, response) => { createReadStream(__filename).pipe(response);}).listen(8080);
上面代码会将这个脚本代码,发送给客户端。这时不用写response.end()
方法,因为pipe()
方法会在发送结束后,自动关闭数据流。
response.setHeader()
方法用于设置返回的头信息。
const { createServer } = require('http');
createServer((req, res) => { res.setHeader('content-type', 'application/json'); res.end(JSON.stringify({ foo: 'bar' }));}).listen(8080);
下面是设置 Cookie 的例子。
const { createServer } = require('http');
createServer((req, res) => { res.setHeader( 'Set-Cookie', ['myCookie=myValue'], ['mySecondCookie=mySecondValue'] ); res.end(`Your cookies are: ${req.headers.cookie}`);}).listen(8080);
response.writeHead()
方法与response.setHeader()
类似,但是优先级更高。它可以设置返回的 HTTP 状态码,第一个参数是状态码,第二个参数是状态说明。
const { createServer } = require('http');
createServer((req, res) => { res.writeHead(204, 'My Custom Message'); res.end();}).listen(8080);
request 对象
request.headers
属性返回一个对象,包含了 HTTP 请求的头信息。该对象的键名是头信息的字段名,键值是头信息的字段值。
const { createServer } = require("http");
createServer((request, response) => { const languages = request.headers['accept-language']; response.end(languages);}).listen(8080);
上面代码返回 HTTP 请求的头信息accept-language
。
request.url
属性返回浏览器请求的路径,可以基于这个属性做一个简单的路由。
const { createServer } = require('http');
createServer((req, res) => { switch (req.url) { case '/': res.end('You are on the main page!'); break; case '/about': res.end('You are on about page!'); break; default: res.statusCode = 404; res.end('Page not found!'); }}).listen(8080);
获取查询字符串,可以用 Node 内置的url
模块解析request.url
属性。
const { createServer } = require('http');
createServer((req, res) => { const { query } = require('url').parse(req.url, true); if (query.name) { res.end(`You requested parameter name with value ${query.name}`); } else { res.end('Hello!'); }}).listen(8080);
request.method
属性返回浏览器请求的方法。
const { createServer } = require('http');
createServer((req, res) => { if (req.method === 'GET') { return res.end('List of data'); } else if (req.method === 'POST') { return res.end('success'); } else { res.statusCode(400); return res.end('Unsupported method'); }}).listen(8080);
POST 请求发送的数据体是一个数据流(stream),可以用request.on()
方法监听data
事件,累加数据流的每一部分;监听end
事件,得到数据流接收结束的通知。
const { createServer } = require('http');
createServer((req, res) => { if (req.method === 'POST') { let data = ''; req.on('data', chunk => { data += chunk; });
req.on('end', () => { try { const requestData = JSON.parse(data); requestData.ourMessage = 'success'; res.setHeader('Content-Type', 'application/json'); res.end(JSON.stringify(requestData)); } catch (e) { res.statusCode = 400; res.end('Invalid JSON'); } }); } else { res.statusCode = 400; res.end('Unsupported method, please POST a JSON object'); }}).listen(8080);