一个HTTP服务器响应 html
var http = require('http'); http.createServer(function(request,response){ response.end('hello world!'); }).listen(3000);
读取请求头及设定响应头node
// res.setHeader(field, value) // res.getHeader(field) // res .removeHeader(field) // 默认状态码200(代表成功) res.setHeader('Content-Type','text/html'); res.writeHead(200,{'Content-Type':'text/html'});
设定HTTP响应的状态码数组
//当所请求的资源不存在时返回一个404 Not Found状态码 //设定res.statusCode属性。在程序响应期间能够随时给这个属性赋值,须要是在第一次调用res.write()或res.end()以前设置. res.statusCode = 302;
用POST请求建立资源安全
var http = require('http'); http.createServer(function(request,response){ request.setEncoding('utf-8'); request.on('data',function(chunk){ console.log( chunk ); }); request.on('end',function(){ console.log('done'); response.end('hello world!'); }); }).listen(3000); //默认状况下,data事件会提供Buffer对象,这是node.js版的字节数组 //不须要二进制数据,调用req.setEncoding(encoding)方法能够将流编码为ascii或utf8,这样data事件会给出字符串
var http = require('http'); var url = require('url'); var items = []; 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; } }).listen(3000);
用GET请求获取资源服务器
var http = require('http'); var url = require('url'); var items = []; http.createServer(function(req, res){ switch (req.method){ case 'POST': //.. break; case 'GET': items.forEach(function(item,index){ res.write(index +'/'+ item +'\n'); res.end(); }); break; } }).listen(3000); //为了提升响应速度,能够在响应中带着Content-Length域一块儿发送 var body = items.map(function(item,index){ return i +'/'+ item; }).join('\n'); res.setHeader('Content-Length',Buffer.byteLength()); res.setHeader('Content-Type','text/plain'); res.end(body);
用DELETE请求移除资源ide
var http = require('http'); var url = require('url'); var items = []; http.createServer(function(req, res){ switch (req.method){ case 'POST': //.. break; case 'GET': //.. break; case 'DELETE': var path = url.parse(req.url).pathname; var i = parseInt(path.slice(1),10); if(isNaN(i)){ res.statusCode = 400; res.end('Invalid item id'); }else if(!items[i]){ res.statusCode = 404; res.end('item nod found'); }else{ items.splice(i,1); res.end('delete done'); } break; } }).listen(3000);
建立一个静态文件服务器优化
每一个静态文件服务器都有个根目录,也就是提供文件服务的基础目录。ui
定义一个root变量,它将做为这个静态文件服务器的根目录。编码
var root = __dirname; //__dirname 的值是该文件所在目录的路径。 //若是有分散在不一样目录中的文件,__dirname能够有不一样的值。
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);
优化数据传输url
node.js中的管道: 是来自源头(即ReadableStream)的数据,管道可让数据流动到某个目的地(即WritableStream),能够用pipe方法把管道连起来。
var readStream = fs.createReadStream('./original.txt') var writeStream = fs.createWriteStream('./copy.txt') readStream.pipe(writeStream); //... var server = http.createServer(function(req, res){ var url = parse(req.url); var path = join(root, url.pathname); //绝对路径 var stream = fs.createReadStream(path); //高层流式硬盘访问文件内容 stream.pipe(res); }); //...
处理服务器错误
若是访问不存在的文件,或者不容许访问的文件,或者碰到任何与文件I/O有关的问题,当前的服务器会抛出错误。
在node.js中,全部继承了EventEmitter的类均可能会发出error事件。
默认状况下,若是没有设置监听器,error事件会被抛出。也就是说若是你不监听这些错误,那它们就会搞垮服务器。
注册一个error事件处理器,能够捕获任何能够预见或没法预见的错误,给客户端更优雅的响应。
//.. stream.pipe(res); stream.on('error',function(error){ res.statusCode = 500; res.end('Invalid Server Error'); }); //..
一个简单的支持GET、POST的HTTP服务器
模板文件 template.html
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>A HTTP Server</title> </head> <body> <ul>%</ul> <form method="POST" action="/"> <p><input type="text" name="item" value="" /></p> <p><input type="submit" value="Add item" /></p> </form> </body> </html>
node.js文件 index.js
var http = require('http'); var fs = require('fs'); var qs = require('querystring'); var items = []; var server = http.createServer(function(req, res){ if(req.url == '/'){ switch (req.method.toUpperCase()){ case 'GET': show(res); break; case 'POST': add(req, res); break; default: badRequest(res); } }else{ notFound(res); } }); server.listen(3000); function show(res){ fs.readFile('./template.html',function(err, data){ var html = data.toString().replace('%', items.map(function(item,index){ return '<li>'+ item +'</li>'; }).join('')); res.setHeader('Content-Type','text/html'); res.setHeader('Content-Length',Buffer.byteLength(html)); res.end(html); }); } function add(req, res){ var body = ''; req.setEncoding('utf8'); req.on('data',function(chunk){ body += chunk; }); req.on('end',function(){ items.push( qs.parse(body).item ); show(res); }); } function notFound(res){ res.statusCode = 404; res.setHeader('Content-Type','text/plain'); res.end('Not Found'); } function badRequest(res){ res.statusCode = 400; res.setHeader('Content-Type','text/plain'); res.end('Bad Request'); }
一个文件上传HTTP服务器
上传文件须要把表单的enctype属性设为multipart/form-data。
formidable模块能够高效流畅的方式解析文件上传请求。
html模板文件: template.html
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>upload file</title> </head> <body> <form method="POST" action="/" enctype="multipart/form-data"> <p><input type="text" name="name"/></p> <p><input type="file" name="file"/></p> <p><input type="submit" value="upload file" /></p> </form> </body> </html>
node.js文件:index.js
var http = require('http'); var fs = require('fs'); var qs = require('querystring'); var formidable = require('formidable') var items = []; var server = http.createServer(function(req, res){ if(req.url == '/'){ switch (req.method.toUpperCase()){ case 'GET': show(res); break; case 'POST': upload(req, res); break; default: badRequest(res); } }else{ notFound(res); } }); server.listen(3000); function show(res){ fs.readFile('./template.html',function(err, data){ var html = data.toString(); res.setHeader('Content-Type','text/html'); res.setHeader('Content-Length',Buffer.byteLength(html)); res.end(html); }); } function upload(req,res){ if(!isFormData(req)){ return badRequest(res); } var form = formidable.IncomingForm(); form.uploadDir = __dirname; //路径设置 // form.on('field',function(field,value){ // console.log(field); // console.log(value); // }); // form.on('file',function(name,file){ // console.log(name); // console.log(file); // }); // form.on('end',function(){ // res.end('upload complate'); // }); // form.parse(req); //上传进度事件 form.on('progress',function(bytesReceived,bytesExpected){ var progress = Math.floor( bytesReceived/bytesExpected*100 ); console.log(progress); }); form.parse(req,function(err,fields,files){ console.log(fields); console.log(files); //console.log( files.file.path ); res.end('upload complate'); }); } function isFormData(req){ var type = req.headers['content-type'] || ''; return type.indexOf('multipart/form-data') == 0; } function notFound(res){ res.statusCode = 404; res.setHeader('Content-Type','text/plain'); res.end('Not Found'); } function badRequest(res){ res.statusCode = 400; res.setHeader('Content-Type','text/plain'); res.end('Bad Request'); }
用https增强程序的安全性
若是想在node.js程序里使用https,第一件事就是取得一个私钥和一份证书。
生成私钥须要OpenSSL,在装node.js时就已经安装了。
生成名为key.pem的私钥文件, 在项目根目录输入命令:openssl genrsa 1024 > key.pem
生成名为key-cert.pem的证书,在项目根目录输入命令:openssl req -x509 -new -key key.pem > key-cert.pem
var https = require('https'); var fs = require('fs'); var options = { key: fs.readFileSync('./key.pem'), cert: fs.readFileSync('./key-cert.pem') }; https.createServer(options,function(req,res){ res.writeHead(200); res.end('hello node.js!'); }).listen(3000);