跳转至

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

参考链接