HTTP 服务器的基础知识
var http=require('http');
http.createServer("/",function(req,res){
res.end("hello");
}).listen(3000);
console.log("start server")
复制代码
-
读取请求头及设定响应头
- Node提供了几个修改HTTP响应头的方法: res.setHeader(field, value)res.getHeader(field) 和 res .removeHeader(field)
- 添加和移除响应头的顺序可以随意,但一定要在调用 res.write() 或 res.end() 之前。在 响应主体的第一部分写入之后,Node会刷新已经设定好的HTTP头。
-
设定HTTP响应的状态码
- 设定 res.statusCode 属性。在程序响应期间可以随时给这个属性赋值,只要是在第一次调用 res.write() 或 res.end() 之前就行。
构建 RESTful Web 服务
用POST请求创建资源
var http = require('http');
var url = require('url');
var items = [];
var server = http.createServer(function(req, res){
switch (req.method) {
case 'POST':
var item = '';
req.setEncoding('utf8');
req.on('data', function(chunk){
item += chunk;
});
req.on('end', function(){
items.push(item);
res.end('OK\n');
});
break;
}
});
复制代码
默认情况下, data 事件会提供 Buffer 对象,这是Node版的字节数组。而对于文本格式的待 办事项而言,你并不需要二进制数据,所以最好将流编码设定为 ascii 或 utf8 ;这样 data 事件 会给出字符串。这可以通过调用 req.setEncoding(encoding) 方法设定。
提供静态文件服务
- 创建一个静态文件服务器
最基本的ReadStream静态文件服务器
var http = require('http');
var parse = require('url').parse;
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);
stream.on('data', function(chunk){
res.write(chunk);
});
stream.on('end', function(){
res.end();
});
});
server.listen(3000);
复制代码
- __dirname 在Node中是一个神奇的变量,它的值是该文件所在目录的路径。 __dirname 的 神奇之处就在于,它在同一个程序中可以有不同的值,如果你有分散在不同目录中的文件的话。
- 用 STREAM.PIPE() 优化数据传输
- 处理服务器错误
- 我们的静态文件服务器还没有处理因使用 fs.ReadStream 可能出现的错误。如果你访问不 存在的文件,或者不允许访问的文件,或者碰到任何与文件I/O有关的问题,当前的服务器会抛 出错误。
- 在Node中,所有继承了 EventEmitter 的类都可能会发出 error 事件。像 fs.ReadStream 这样的流只是专用的 EventEmitter ,有预先定义的 data 和 end 等事件,我们已经看过了。默认 情况下,如果没有设置监听器, error 事件会被抛出。也就是说如果你不监听这些错误,那它们 就会搞垮你的服务器。
- 为了防止服务器被错误搞垮,我们要监听错误,在 fs.ReadStream 上注册一个 error 事件 处理器(比如下面这段代码),返回响应状态码500表明有服务器内部错误:
用 fs.stat() 实现先发制人的错误处理
fs.stat() 用于得到文件的相关信息,比如它的大小,或者得到错误码。如果文件不存在, fs.stat() 会在 err.code 中放入 ENOENT作为响应,然后你可以返回错误码404,向客户端表明文件未找到。如果 fs.stat() 返回了其他 错误码,你可以返回通用的错误码500。
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);
var stream = fs.createReadStream(path);
stream.pipe(res);
stream.on('error', function(err){
res.statusCode = 500;
res.end('Internal Server Error');
});
}
});
});
复制代码
从表单中接受用户输入
处理提交的表单域
表单提交请求带的 Content-Type 值通常有两种:
- application/x-www-form-urlencoded :这是HTML表单的默认值;
- multipart/form-data :在表单中含有文件或非ASCII或二进制数据时使用。
- 支持GET和POST的HTTP服务器
var http = require('http');
var items = [];
var server = http.createServer(function(req, res){
if ('/' == req.url) {
switch (req.method) {
case 'GET':
show(res);
break;
case 'POST':
add(req, res);
break;
default:
badRequest(res);
}
} else {
notFound(res);
}
});
server.listen(3000);
复制代码
- 待办事项列表页面的表单和事项列表
- QUERYSTRING模块
用formidable处理上传的文件
参考《Node.js in Action》的4.4.2
计算上传进度
Formidable的 progress 事件能给出收到的字节数,以及期望收到的字节数。我们可以借助 这个做出一个进度条。
用 HTTPS 加强程序的安全性
HTTPS服务器配置项
例子中所用的证书不是由证书颁发机构颁发的,所以会 显示一个警告信息。这里可以忽略这个警告,但如果要把网站部署到公网上,你就应该找个证书 颁发机构(CA)进行注册,并为你的服务器取得一份真实的、受信的证书。