大纲:
1: Node可以做什么?
搭建服务器,接收响应请求。
我用的window 去下个安装文件,一键安装即可。
2:Hello World
var http = require("http"); //引入require模块
//创建服务
http.createServer(function(request,response){
//发送HTTP头,状态200,内容类型'text/plain'
response.writeHead(200,{'Content-Type':'text/plain'});
response.end("Hello World\n") //发送响应数据
}).listen(8888);
console.log('Server running at http://localhost:8888');
3:Npm 安装 node的时候会一起安装。
4: 阻塞与非阻塞代码对比
5:node事件机制
Node.js 基本上所有的事件机制都是用设计模式中的观察者模式实现。
Node.js使用事件驱动模型,当web server接收到请求,就把它关闭后进行处理,
然后去服务下一个web请求。当这个请求完成,它被放回处理队列,当到达队列
开头,这个结果被返回给用户。
var events = require('events');
var eventEmitter = new events.EventEmitter();
//创建事件处理程序
var connectHandler = function connected(){
console.log('链接成功!');
eventEmitter.emit('data_received'); //触发data_received事件
}
eventEmitter.on('connection',connectHandler); //绑定处理程序
eventEmitter.on('data_received',function(){
console.log('数据接收成功。'); //使用匿名函数绑定data_received事件
});
eventEmitter.emit('connection'); //触发connection事件
console.log("程序执行完毕。");
//下面是读取文件实例:
var fs = require("fs");
fs.readFile('input.txt',function(err,data){
if(err) return console.error(err.stack);
console.log(data.toString());
});
console.log("end!");
//如果没有错误则会先输出end然后输出文件内容。
//如果有错误则输出错误。
6: EventEmitter
一个事件可以添加多个监听
var events = require('events');
var event = new events.EventEmitter();
event.on('some_event',function(arg1,arg2){
console.log('listener1',arg1,arg2);
});
event.on('some_event',function(arg1,arg2){
console.log('listener2',arg1,arg2);
});
event.emit('some_event','11111','22222')
//打印出来:
//listener1 11111 22222
//listener2 11111 22222
EventEmitter属性介绍:
方法:
addListener(event,listener)
on(event,listener)
once(event,listener) //只触发一次
removeListener(event,listener) //移除某个指定的监听
removeAllListeners([event])
setMaxListeners(n) //默认情况下如果EventEmitters如果添加的监听器超过10个就会输出警告信息。
listeners(event) //返回指定事件的监听器组
emit(event,[arg1],[arg2,[…]]) 按照参数的顺序执行每个监听器。
类方法:
listenerCount(emitter,event) //返回指定事件的监听器数量。
事件:
newListener evnet - 字符串,处理事件函数,该事件在添加新监听器时被触发。
removeListener event - 字符串,移除监听器。
(一般不会直接使用 EventEmitter ,而是在对象中继承它。)
7:Stream 常用的流操作
四种流类型:
Readable 可读操作。
Writable 可写操作。
Duplex 可读可写操作。
Transform 操作被写入数据,然后读出结果。
常用事件有:
data 当有数据可读时触发。
end 没有更多的数据可读时触发。
error 在接收和写入过程中发生错误时触发。
finish 所有数据已被写入到底层系统时触发。
创建可读流:
var fs = require('fs');
var data = '';
//创建可读流
var readerStream = fs.createReadStream('input.txt');
readerStream.setEncoding('UTF8');
readerStream.on('data',function(chunk){
data += chunk;
});
readerStream.on('end',function(){
console.log(data);
});
readerStream.on('error',function(err){
console.log(err.stack);
});
console.log("程序执行完毕");
创建写入流
var fs = require('fs');
var data = '写入流测试 。。。。。。';
//创建写入流
var writerStream = fs.createWriteStream('input.txt');
writerStream.write(data,'UTF8');
writerStream.end();
writerStream.on('finish',function(){
console.log("写入完成。");
});
writerStream.on('error',function(err){
console.log(err.stack);
});
console.log("程序执行完毕");
8:模块系统
//最简例子:
main.js--------------------------
var hello = require('./hello');
hello.world();
hello.js---------------------------
exports.world = function(){
console.log("Hello World!");
}
//所以可以下面这样定义类
function Hello(){
var name;
this.setName = function(thyName){
name = thyName
};
this.sayHello = function(){
console.log('Hello '+name);
};
};
module.exports = Hello;
//如下调用即可
var Hello = require('./hello');
hello = new Hello();
hello.setName('myName');
hello.sayHello();
9:Node.js 路由
例子如下:
//server.js --------------------------------
var http = require("http");
var url = require("url");
function start(route){
console.log("..................");
function onRequest(request,response){
var pathname = url.parse(request.url).pathname;
console.log("Request for "+pathname+"received.");
route(pathname);
response.writeHead(200,{"Content-Type":"text/plain"});
response.write("Hello World");
response.end();
}
http.createServer(onRequest).listen(8888);
console.log("server has started.");
}
exports.start = start;
//index.js-----------------------------------------
var server = require("./server");
var router = require("./router");
server.start(router.route);
//router.js-------------------------------------------
function route(pathname){
console.log("About to route a request for "+pathname);
}
exports.route = route;
10: 全局变量和全局函数
最简单的两个例子:
console.log(__filename);
console.log(__dirname); //__filename和__dirname是全局变量
function printHello(){
console.log(“Hello World!”);
};
setTimeout(printHello,2000); //setTimeout是全局函数
11:util是Node.js核心模块。
其方法如下:
util.inherits(constructor,superConstructor) 实现对象间原型继承
util.inspect(object,[showHidden],[depth],[colors]) 将任意对象转换为字符串
util.isArray(object)
util.isRegExp(object)
util.isDate(object)
util.isError(object)
12:get请求与post请求
var http = require('http');
var url = require('url');
var util = require('util');
http.createServer(function(req,res){
res.writeHead(200,{'Content-Type':'text/plain'});
res.end(util.inspect(url.parse(req.url,true)));
}).listen(3000);
var http = require("http");
var querystring = require("querystring");
var util = require("util");
http.createServer(function(req,res){
var post="";
req.on('data',function(chunk){
post += chunk;
});
req.on('end',function(){
post = querystring.parse(post);
res.end(util.inspect(post));
});
}).listen(3000);
13:构建Web服务器
(1)建立一个html模板
<!DOCTYPE html>
<html>
<head>
<title>Sample Page</title>
</head>
<body>
Hello World!
</body>
</html>>
(2)建立server服务可以返回这个模板信息
var http = require("http");
var fs = require("fs");
var url = require("url");
http.createServer(function(request,response){
var pathname = url.parse(request.url).pathname;
console.log("Request for " + pathname + " received.");
fs.readFile(pathname.substr(1),function(err,data){
if(err){
console.log(err);
response.writeHead(404,{'Content-Type':'text/html'});
}else{
response.writeHead(200,{'Content-Type':'text/html'});
console.log(data.toString());
response.write(data.toString());
}
response.end();
});
}).listen(8081);
console.log('Server running at http://localhost:8081/');
(3)建立一个客户端client.js可以请求server
var http = require('http');
var options = {
host:'localhost',
port:'8081',
path:'/index.htm'
}
var callback = function(res){
var body = "";
res.on('data',function(data){
body += data;
});
res.on('end',function(){
console.log(body);
});
}
var req = http.request(options,callback);
req.end();
server和client分别用两个终端(cmd)打开并运行。可以通过客户端得到服务端发送过来的页面。
14:Node.js 文件系统
var fs = require(‘fs’);
简单记录语法:
fs.open(path,flags[,mode],callback) //打开文件
fs.stat(path,callback) //获取文件信息
fs.writeFile(filename,data[,options],callback) //写入文件
fs.read(fd,buffer,offset,length,position,callback) //读取文件
fs.close(fd,callback) //关闭文件
fs.ftruncate(fd,len,callback) //异步截取文件
fs.unlink(path,callback) //删除文件
fs.mkdir(path[,mode],callback); //创建目录
fs.readdir(path,callback) //读取目录
fs.rmdir(path,callback) //删除目录
15: JXcore
可以用 JXcore 打包 Node.js 代码,这里暂不记录,需要了解的时候按步骤下载操作即可。
16:Node.js RESTful API
REST表述性状态传递。所以REST是设计风格,不是标准。REST通常是json数据格式。
基于REST架构的Web Service即是RESTful
HTTP方法: GET PUT DELETE POST
这个跟extjs 的json有点类似
写一个json文件 users.json
{
"user1":{
"name":"mahesh",
"password":"password1",
"profession":"teacher",
"id":1
},"user2":{
"name":"suresh",
"password":"password2",
"profession":"librarian",
"id":2
},"user3":{
"name":"ramesh",
"password":"password3",
"profession":"clerk",
"id":3
}
}
用js把这个json显示出来 rest_server.js,就是读取json数据。
var express = require("express");
var app = express();
var fs = require("fs");
app.get('/listUsers',function(req,res){
fs.readFile(__dirname+"/"+"users.json",'utf8',function(err,data){
console.log(data);
res.end(data);
});
})
var server = app.listen('8081',function(){
console.log("http://localhost:8081/")
})
当然也可以读取数据删除数据,这里不做记录。
17:Express简介
特性:
可以设置中间件来响应HTTP请求
定义了路由表用于执行不同的HTTP请求动作。
可以通过向模板传递参数来动态渲染html界面。
首先安装相关依赖包。
npm install express -g
npm install body-parser -g
npm install cookie-parser -g
npm install multer -g
第一个实例:
var express = require("express");
var app = express();
app.get('/',function(req,res){
res.send('Hello World');
})
var server = app.listen(8081,function(){
var host = server.address().address
var port = server.address().port
console.log("应用实例访问地址为 http://%s:%s",host,port)
})
访问http://localhost:8081/
路由:
可以通过路由提出请求的URL以及GET/POST参数。
例子:
var express = require("express");
var app = express();
app.get('/',function(req,res){
console.log("主页 GET 请求");
res.send('Hello GET');
})
//post请求
app.post('/',function(req,res){
console.log("主页 POST 请求");
res.send('Hello POST');
})
// /del_user 页面响应
app.delete('/del_user',function(req,res){
console.log("/del_user 页面响应 DELETE 请求");
res.send('删除页面');
})
// /list_user 页面get请求
app.get('/list_user',function(req,res){
console.log("/list_user GET 请求");
res.send('用户列表页面');
})
// 对页面 abcd,abxcd,ab123cd 等响应GET请求
app.get('/ab*cd',function(req,res){
console.log("/ab*cd GET 请求");
res.send("正则匹配");
})
var server = app.listen(8081,function(){
var host = server.address().address
var port = server.address().port
console.log("应用实例访问地址为 http://%s:%s",host,port)
})
通过app的方法,配合字符串或者表达式匹配连接,让连接走入不同的页面。
静态文件:
如果我们有一个图片向通过路径展示出图片,这就需要我们在连接中输入静态路径。
例如:我们的js下设置一个名字叫public的文件夹,它下面有一个image文件夹,里面有个图片叫 aa.jpg
我们如果想展示这个aa.jpg文件则需要
设置 app.use(express.static(‘public’)); 请求则是 http://localhost:8081/image/aa.jpg即可。
例子代码:
var express = require("express");
var app = express();
//设置静态目录
app.use(express.static('public'));
app.get('/',function(req,res){
console.log("主页 GET 请求");
res.send('Hello GET');
})
var server = app.listen(8081,function(){
var host = server.address().address
var port = server.address().port
console.log("应用实例访问地址为 http://%s:%s",host,port)
})
请求:http://localhost:8081/image/aa.png
get 方法实例:
index_get.html页面
<!DOCTYPE html>
<html>
<body>
<form action='http://localhost:8081/process_get' method="GET">
First Name: <input type="text" name="first_name"> <br>
Last Name: <input type="text" name="last_name">
<input type="submit" name="Submit">
</form>
</body>
</html>
server_get.js页面
var express = require("express");
var app = express();
app.use(express.static('public'));
app.get('/index_get.html',function(req,res){
res.sendFile(__dirname + "/" + "index_get.html");
})
app.get('/process_get',function(req,res){
//输出json格式
response = {
first_name:req.query.first_name,
last_name:req.query.last_name
}
console.log(response);
res.end(JSON.stringify(response));
})
var server = app.listen(8081,function(){
var host = server.address().address
var port = server.address().port
console.log("应用实例访问地址为 http://%s:%s",host,port)
})
//http://localhost:8081/index_get.html 请求路径,填写信息后提交可以进入到process_get页面
//注意 sendFile 和 send的用法。
下面是post方法,用get来做对比:
(1)首先html页面的form参数修改为
请求post方法,method也修改为POST
(2)调用body-parser
var bodyParser = require(“body-parser”);
//创建编码解析器
var urlencodeParser = bodyParser.urlencoded({extended:false})
(3)接收post
app.post(’/process_post’,urlencodeParser,function(req,res){
(4)取参数
req.body.first_name
以上是post与get请求的不同。
目前所接触到的细节:
(1)创建编码解析器
var urlencodeParser = bodyParser.urlencoded({extended:false})
使用
app.post(’/process_post’,urlencodeParser,function(req,res){
(2)输出文件 res.sendFile(__dirname + “/” + “index_get.html”);
(3)app.post , app.get
(4)req.query.first_name //get取值
req.body.first_name //post取值
(5)监听借口var server = app.listen(8081,function(){ … })
(6)页面输出信息
res.sendFile(__dirname+"/"+“XXX.html”)
res.send("")
res.end(JSON.stringify(response))
(7)设置静态路径: app.use(express.static(‘public’));
入门的最后一个例子:
文件上传:
新建一个上传文件的页面:index_upload.html:
文件上传:
选择一个文件上传新建js文件 upload_server.js
var express = require("express");
var app = express();
var fs = require("fs");
var bodyParser = require("body-parser");
var multer = require("multer");
app.use(express.static('public'));
app.use(bodyParser.urlencoded({extended:false}));
app.use(multer({dest:'/tmp/'}).array('image'))
app.get('/index_upload.html',function(req,res){
res.sendFile(__dirname+"/"+"index_upload.html")
})
app.post('/file_upload',function(req,res){
console.log(req.files[0]);//上传文件信息
let des_file = __dirname + "/" + req.files[0].originalname;
fs.readFile(req.files[0].path,function(err,data){
fs.writeFile(des_file,data,function(err){
if(err){
console.log(err);
}else{
response = {
message:'File upload successfully',
filename:req.files[0].originalname
};
}
console.log(response);
res.end(JSON.stringify(response));
});
});
})
var server = app.listen('8081',function(){
console.log("http://localhost:8081/index_upload.html")
})
http://localhost:8081/index_upload.html 运行 ,可以把文件下载到项目指定目录下。
例子很简单,但是运行的时候出现multer没有的错误
尝试全局安装两次,没效果,本地安装还是没用,把文件拿出来
在本地重新安装express和multer才好用。
最后:
Cookie管理了解一下。
下面代码输出了客户端发送的cookie信息。
var express = require('express')
var cookieParser = require('cookie-parser')
var app = express()
app.use(cookieParser)
app.get('/index_upload.html',function(req,res){
console.log("Cookie:",req.cookies)
res.sendFile(__dirname+"/"+"index_upload.html")
})
总结一下,请求响应,路由重定向,静态文件,GET,POST 文件上传下载 Cookie管理