第四章:构建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服务器: