一个HTTP服务器响应   

var http = require('http');
http.createServer(function(request,response){
response.end('hello world!');
}).listen(3000);

  读取请求头及设定响应头

// 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请求移除资源

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

  创建一个静态文件服务器

   每个静态文件服务器都有个根目录,也就是提供文件服务的基础目录。

   定义一个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);

  优化数据传输

   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>

template

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

node.js code

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

node.js基础:HTTP服务器的更多相关文章

  1. Node.js 创建HTTP服务器

    Node.js 创建HTTP服务器 如果我们使用PHP来编写后端的代码时,需要Apache 或者 Nginx 的HTTP 服务器,并配上 mod_php5 模块和php-cgi. 从这个角度看,整个& ...

  2. Node.js 创建HTTP服务器(经过测试,这篇文章是靠谱的T_T)

    Node.js 创建HTTP服务器 如果我们使用PHP来编写后端的代码时,需要Apache 或者 Nginx 的HTTP 服务器,并配上 mod_php5 模块和php-cgi. 从这个角度看,整个& ...

  3. Node.js基础知识

    Node.js入门   Node.js     Node.js是一套用来编写高性能网络服务器的JavaScript工具包,一系列的变化由此开始.比较独特的是,Node.js会假设在POSIX环境下运行 ...

  4. 10慕课网《进击Node.js基础(一)》初识promise

    首先用最简单的方式实现一个动画效果 <!doctype> <html> <head> <title>Promise animation</titl ...

  5. 进击Node.js基础(二)

    一.一个牛逼闪闪的知识点Promise npm install bluebird 二.Promise实例 ball.html <!doctype> <!DOCTYPE html> ...

  6. 01慕课网《进击Node.js基础(一)》Node.js安装,创建例子

    版本:偶数位为稳定版本,基数为非稳定版本 - 0.6.x - 0.7.x    - 0.8.x -0.9.x    -0.10.x  -0.11.x 概念:Node.js采用谷歌浏览器的V8引擎,用C ...

  7. Node.js基础与实战

    Node.js基础与实战 Node.jsJS高级进阶 NODE原理与解析 REPL交互环境 模块与NPM Buffer缓存区 fs文件操作 Stream流 TCP&UDP 异步编程 HTTP& ...

  8. node.js基础模块http、网页分析工具cherrio实现爬虫

    node.js基础模块http.网页分析工具cherrio实现爬虫 一.前言      说是爬虫初探,其实并没有用到爬虫相关第三方类库,主要用了node.js基础模块http.网页分析工具cherri ...

  9. 使用 Node.js 搭建 Web 服务器

    使用Node.js搭建Web服务器是学习Node.js比较全面的入门教程,因为实现Web服务器需要用到几个比较重要的模块:http模块.文件系统.url解析模块.路径解析模块.以及301重定向技术等, ...

  10. NodeJs>------->>第三章:Node.js基础知识

    第三章:Node.js基础知识 一:Node.js中的控制台 1:console.log.console.info  方法 console.log(" node app1.js 1> ...

随机推荐

  1. 初始化openwrt的rootpassword

    更改openwrt源代码 shadow 文件 package/base-files/files/etc/shadow shadow 文件參考http://blog.csdn.net/u01164188 ...

  2. hdu4635(强连通缩点)

    传送门:Strongly connected 题意:求最多可以加多少边,使得最新的图还不是强连通图. 分析:最终添加完边的图,肯定可以分成两个部X和Y,其中只有X到Y的边没有Y到X的边,那么要使得边数 ...

  3. C++ Primer 学习笔记_61_重载操作符与转换 --自增/自减操作符

    重载操作符与转换 --自增/自减操作符 引言: 自增,自减操作符常常由诸如迭代器这种类实现,这种类提供相似于指针的行为来訪问序列中的元素.比如,能够定义一个类,该类指向一个数组并为该数组中的元素提供訪 ...

  4. LeetCode_Merge Two Sorted Lists

    一.题目 Merge Two Sorted Lists My Submissions Merge two sorted linked lists and return it as a new list ...

  5. ADN中国团队參加微软的Kinect全国大赛获得三等奖

    上周末我们团队參加了微软的Kinect全国大赛,我们的Kinect + Navisworks漫游荣膺三等奖   团队经理Joe写了篇详实的总结,我就直接转载了. http://blog.csdn.ne ...

  6. OpenStack安装与配置2

    第二部分 OpenStack安装与配置 一.引言   本章内容讲解如何在3台物理机上搭建最小化云平台,这3台机器分为称为Server1.Server2和Client1,之后的各章也是如此.Server ...

  7. Learning Cocos2d-x for WP8(6)——场景切换和场景过渡效果

    原文:Learning Cocos2d-x for WP8(6)--场景切换和场景过渡效果 C#(wp7)兄弟篇 Learning Cocos2d-x for XNA(6)——场景切换和场景过渡效果 ...

  8. U7Linux文件与目录管理

    1. .:代表当前层目录. ..:代表上一层目录. -:代表前一个工作目录. ~:代表目前用户所在的主文件夹. ~account:代表account这个用户的主文件夹. 2.pwd:显示当前目录. p ...

  9. Codeforces #252 (Div. 2) B. Valera and Fruits

    题目倒是不难,可是读起来非常恶心 依据题目的描写叙述不easy找到适合存储的方法 后来我就想不跟着出题人的思路走 我自己开一个数组c 令c[a[i]] = b[i] 则c[i] == [j] 代表第i ...

  10. ocx控件手动修改clsid的方法

    替换掉工程的两个地方:IDL文件和CTRL文件. IMPLEMENT_OLECREATE_EX(CMultiwndCtrl, "MULTIWND.MultiwndCtrl.1", ...