《Node.js 实战》读书笔记(三)

147 阅读3分钟

第四章:构建Node Web程序(底层API)

一、Node Web程序分层概览

二、HTTP模块

var http = require('http')
http.createServer(function(req,res){// 回调函数的参数为req和res
  res.write();// 将响应数据写到socket中
  res.end();// 结束响应
}) 
server.listen(3000) // 绑定端口,监听接入

服务器每收到一条HTTP请求,都会用新的req和res对象触发请求回调函数。在触发回调函数之前,Node会解析请求的HTTP头,并将它们作为req对象的一部分提供给请求回调。但Node不会在回调函数被触发之前开始对请求体的解析。

1、请求响应流程

2、HTTP处理响应头方法(响应头的操作应该在res.write()或 res.end()之前。在响应主体的第一部分写入之后,Node会刷新已经设定好的HTTP头)

  • res.setHeader(field, value)
  • res.getHeader(field)
  • res .removeHeader(field)

3、HTTP设置响应状态码(在res.write()或 res.end()之前) res.statusCode = 302

三、构建 RESTful Web 服务 —— REST表征状态转移

1、定义

一个使用HTTP方法谓词提供精简API的服务。HTTP谓词如GET、POST、PUT和DELETE,分别跟由URL指定的资源 的获取、创建、更新和移除相对应,涉及到典型的创建、读取、更新和删除(CRUD)操作。

四、url模块的parse()函数

url.parse()可以帮助解析URL请求中的参数,输出一个对象。

五、提供静态文件服务

1、创建一个静态文件服务器
var http = require('http');
var parse = require('url').parse;// 获取URL参数
var join = require('path').join;// 联接
var fs = require('fs');

var root = __dirname;// 该文件所在目录的路径

var server = http.createServer(function(req, res){
  var url = parse(req.url);
  var path = join(root, url.pathname);// 构造绝对路径
  var stream = fs.createReadStream(path);// 创建fs.ReadStream
  stream.on('data', function(chunk){// 将文件数据写到响应中
    res.write(chunk);
  });
  stream.on('end', function(){
    res.end();// 结束响应
  });
});

server.listen(3000);

__dirname 在Node中是一个神奇的变量,它的值是该文件所在目录的路径。__dirname的 神奇之处就在于,它在同一个程序中可以有不同的值,如果你有分散在不同目录中的文件的话。

2、用STREAM.PIPE()优化数据传输
  • 管道可以将来自源头ReadableStream的数据,让它们“流动”到某个目的地(即WritableStream)。 ReadableStream.pipe(WritableStream);
  • 读取一个文件(ReadableStream)并把其中的内容写到另一个文件中(WritableStream)用 的就是管道:
    var readStream = fs.createReadStream('./original.txt')
    var writeStream = fs.createWriteStream('./copy.txt')
    readStream.pipe(writeStream);
// 优化
  var url = parse(req.url);
  var path = join(root, url.pathname);// 构造绝对路径
  var stream = fs.createReadStream(path);// 创建fs.ReadStream
  stream.pipe(res) // res.end会在内部调用

3、添加错误处理机制

stream.pipe(res)
stream.on('error', function(){// 注册一个error事件处理器
    res.statusCode = 500
    res.end('Error');// 结束响应
  });

4、用fs.stat()实现先发制人的错误处理

  • 获取文件相关信息如修改时间、字节数等,可以检查请求缓存是否过期。
var server = http.createServer(function(req, res){
  var url = parse(req.url);
  var path = join(root, url.pathname);
  fs.stat(path, function(err, stat){// 获取文件的相关信息
    if (err) {
      if ('ENOENT' == err.code) {// 文件不存在
        res.statusCode = 404;
        res.end('Not Found');
      } else {// 其他错误
        res.statusCode = 500;
        res.end('Internal Server Error');
      }
    } else {
      res.setHeader('Content-Length', stat.size);// 用stat对象的属性设置Content-Length
      var stream = fs.createReadStream(path);
      stream.pipe(res);
      stream.on('error', function(err){
        res.statusCode = 500;
        res.end('Internal Server Error');
      });
    }
  });
});

六、从表单中接受用户输入

  • 获取表单数据
  • 用formidable处理上传的文件

七、用 HTTPS 加强程序的安全性

安全的超文本传输协议(HTTPS)提供了一种保证Web会话私密性的方法。HTTPS将HTTP 和TLS/SSL传输层结合到一起。用HTTPS发送的数据是经过加密的,因此更难窃听。

在Node使用HTTPS,第一件事就是取得一个私钥和一份证书。私钥本质上是个“秘钥”,可以用它来解密客户端发给服务器的数据。私钥保存在服务器上的一个文件里,放在一个不可信用户无法轻易访问到的地方。

在node的命令行中可以生产私钥和证书,并跟服务器脚本放在同一个目录下。

创建HTTPS服务器: