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);