前言
为什么会想到搞一下node呢,emmmm,主要是之前想收图片,每个人4张,一共几十个人,如果都通过qq发过来那简直市场噩梦(虽然我最后还是经历了这擦会给你噩梦),所以下定决心要搞一下后端的东西,PHP,ASP学习成本有点高,速成还是有点难,所以我想到了node.js这个神奇的东西,用js的语言来写后端的东西,nice哦。所以就有了这篇文章。
正文
EventEmitter模块
这个模块可以说是node中一个核心的模块,包括fs,http,net等模块的事件都是继承自该模块,若不使用继承的方法,其基本用法是:
//引入events模块
var eventEmitter = require('events');
//创建eventEmitter
var events = new events.EventEmitter();
event.on('some_event1',function(){
console.log("监听器1执行");
})
event.addListener('some_event2',function(){
console.log("监听器2执行");
})
event.removeListener('some_event1',function(){
console.log("监听器1移除");
})
event.emit('some_event1');
这是一些基本的用法,不过这个方法在平时不怎么用,所以了解一下就ok了。
文件系统fs
异步与同步
由于node是基于JS,所以异步与同步是不可回避的一个问题,在之前的博文中,我们也解析过JS的异步与同步操作,这里不再赘述。而node中文件操作是同时支持异步与同步操作,具体区别这里也不再赘述。
异步与同步代码
var fs = require('fs');
//异步读取
fs.readFile('input.txt',function(err,data){
if(err){
return console.error(err);
}
console.log('异步读取'+data.toString());
});
//同步读取
var data = fs.readFileSync('input.txt');
console.log("同步读取:"+dataString());
console.log('文件操作完毕');
注意这里是展示同步与异步的代码区别,一般是在操作代码后加上“Sync”(同步),但一般我们并不使用这种同步的方法,因为在文件大一点的时候这会严重影响代码执行的效率。
打开文件
语法格式
fs.open(path,flag,callback)
参数
path-文件路径
flag-文件打开的模式
callback-回调函数,该函数带有两个参数(err,fd),err->错误,fd-fileData,文件内容及信息
下面是flag的参数及其说明
获取文件信息
语法格式
fs.stat(path,callback)
参数
path-文件路径
call-回调函数
var fs = require('fs');
fs.stat('/Users/liuht/code/itbilu/demo/fs.js', function (err, stats) {
console.log(stats.isFile()); //true
})
下面是该类中的方法:
写入文件
语法格式
fs.writeFile(file,data[,option],callback)
参数
file-文件名或文件描述
data-要写入的数据,可以是字符串(String)或缓冲变量(Buffer)对象
option-该参数是一个对象,包含{encoding,mode,flag}。默认为{utf8,0666,w}
callback-回调函数(仅包含err,在写入失败时返回)
var fs = require('fs');
console.log('准备写入文件');
fs.writeFile('input.txt','我是通过fs.file写入的内容',function(err){
return console.log(err);
}
console.log('数据写入成功!');
console.log('读取写入的数据!');
fs.readFile('input.txt',function(err,data){
if(err){
return console.log(err);}
console.log('读取文件内容:'+data.toString());
});
});
这是代码执行效果:
$ node file.js
准备写入文件
数据写入成功!
读取写入的数据!
异步读取文件数据: 我是通 过fs.writeFile 写入文件的内容
读取文件
语法格式
fs.readFile(fd,buffer,offset,length,position,callback)
参数
fd - 通过 fs.open() 方法返回的文件描述符。
buffer - 数据写入的缓冲区。
offset - 缓冲区写入的写入偏移量。
length - 要从文件中读取的字节数。
position - 文件读取的起始位置,如果 position 的值为 null,则会从当前文件指针的位置读取。
callback - 回调函数,有三个参数err, bytesRead, buffer,err 为错误信息, bytesRead 表示读取的字节数,buffer 为缓冲区对象。
var fs = require("fs");
var buf = new Buffer.alloc(1024);
console.log("准备打开已存在的文件!");
fs.open('input.txt', 'r+', function(err, fd) {
if (err) {
return console.error(err);
}
console.log("文件打开成功!");
console.log("准备读取文件:");
fs.read(fd, buf, 0, buf.length, 0, function(err, bytes){
if (err){
console.log(err);
}
console.log(bytes + " 字节被读取");
// 仅输出读取的字节
if(bytes > 0){
console.log(buf.slice(0, bytes).toString());
}
});
});
下面是代码执行效果:
$ node file.js
准备打开已存在的文件!
文件打开成功!
准备读取文件:
25 字节被读取
This is a test inputtxt
关闭文件
fs.close(fd,callback)
参数
fd - 通过 fs.open() 方法返回的文件描述符。
callback - 回调函数,没有参数。
fs.close(fd, function(err){
if (err){
console.log(err);
}
console.log("文件关闭成功");
截取文件
fs.ftruncate(fd,len,callback)
参数
fd - 通过 fs.open() 方法返回的文件描述符。
len - 文件内容截取的长度。
callback - 回调函数,没有参数(但含有err参数)。
fs.read(fd, buf, 0, buf.length, 0, function(err, bytes){
if (err){
console.log(err);
}
// 仅输出读取的字节
if(bytes > 0){
console.log(buf.slice(0, bytes).toString());
}
删除文件
fs.unlink(path,callback)
参数
path-路径
callback-回调函数,没有参数(但含有err参数)
实例
var fs = require('fs');
console.log('开始删除文件!');
fs.unlink('input.txt',function(err){
if(err){
return console.log(err);
}
console.log("删除成功!");
})
创建目录
fs.mkdir(path,[,mode],callback)
参数
path - 文件路径。
mode - 设置目录权限,默认为 0777。
callback - 回调函数,没有参数。
实例
var fs = require('fs');
console.log('创建目录 /tmp/test/');
fs.mkdir("/tmp/test/",function(err){
if(err){
return console.log(err);
}
console.log('目录创建成功');
})
这是执行效果
$ node file.js
创建目录 /tmp/test/
目录创建成功。
###读取目录###
语法
fs.readdir(path,callback)
参数
path - 文件路径。
callback - 回调函数,回调函数带有两个参数err, files,err 为错误信息,files 为 目录下的文件数组列表。
实例
var fs = require("fs");
console.log("查看 /tmp 目录");
fs.readdir("/tmp/",function(err, files){
if (err) {
return console.error(err);
}
files.forEach( function (file){
console.log( file );
});
});
执行效果
$ node file.js
查看 /tmp 目录
input.out
output.out
test
test.txt
###删除目录###
语法
fs.rmdir(path,callback)
实例
var fs = require("fs");
// 执行前创建一个空的 /tmp/test 目录
console.log("准备删除目录 /tmp/test");
fs.rmdir("/tmp/test",function(err){
if (err) {
return console.error(err);
}
console.log("读取 /tmp 目录");
fs.readdir("/tmp/",function(err, files){
if (err) {
return console.error(err);
}
files.forEach( function (file){
console.log( file );
});
});
});
执行效果:
$ node file.js
准备删除目录 /tmp/test
读取 /tmp 目录
……
文件模块还有很多方法,具体可以参见node.js官方文档
http模块
http模块一般是使用createServer方法来创建服务器,下面是
不使用html文件的代码:
//获取http方法并定义到变量
var http = require('http');
http.createServer(function(req,res){
res.writeHead(400,{'Content-Type':'text/html'})
res.end("This is a test");
}).listen(3000);
console.log("server running at http://127.0.0.1:3000/");
这个代码执行后会在网页上显示This is a test 的字样。
下面是使用html文件来作为网页显示:
var http = require('require');
var fs = require('fs');
var url = require('');
//创建服务器
http.createServer(function(req,res){
//解析请求,包括文件名
var pathname = url.parse(req.url).pathname;
//从文件系统中请求文件内容
console.log('request for'+pathname+'received');
fs.readFile(pathname.substr(1),function(err,data){
if(err){
console.lor(err);
//发送404(未查找到文件)HTTP状态码并规定解析文件为html文件
res.writeHead(404,{'Content-Type':'text/html'});
}else{
//发送200(正常)HTTP状态码并规定解析文件为html
res.writeHead(200,{'Content-Type':'text/html'});
//响应文件内容
res.write(data.toString());
})
res.end();
}).listen(3000);
console.log("Server running at http://127.0.0.1:3000/");
index文件:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
</head>
<body>
<h1>我的第一个标题</h1>
<p>我的第一个段落。</p>
</body>
</html>
执行上面JS代码,并在浏览器中填入:http://127.0.0.1:8080/index.html,就会显示出index.html网页内容。
url及post和get请求
url是指请求的地址,其中不仅包含路径,还了可以包含多个参数,如下图,网址
‘http://user:pass@sub.host.com:8080/p/a/t/h?query=string#hash‘
以下代码可以从url中获取相关的参数:
var http = require('http');
var url = require('url');
var util = require('util');
http.createServer(function(req,res){
res.writeHead(200,{'Content-Type':'text/html';'charset=utf-8'});
res.end(util.inspect(url.parse(req.url,true)));
}).listen(3000);
其效果:
其中util模块是一个工具模块,提供了很多功能,其中util.inspect(object[,options]),这里option的选项很多,这里不再展开叙述。其作用是一个将任意对象转换 为字符串的方法,通常用于调试和错误输出。
将url中的属性值提取出来,
var http = require('http');
var url = require('url');
var util = require('util');
http.createServer(function(req,res){
res.writeHead(200,{'Conten-Type':'text/plain'});
var params = url.parse(req.url,true).query;
res.write("网站名:"+params.name);
res.write("\n");
res.write("网站URL:"params.url);
res.end();
}).listen(3000);
效果:
获取表单数据
var http = require('http');
var querystring = require('querystring');
var postHTML =
'<html><head><meta charset="utf-8"><title>菜鸟教程 Node.js 实例</title></head>' +
'<body>' +
'<form method="post">' +
'网站名: <input name="name"><br>' +
'网站 URL: <input name="url"><br>' +
'<input type="submit">' +
'</form>' +
'</body></html>';
http.createServer(function (req, res) {
var body = "";
req.on('data', function (chunk) {
body += chunk;
});
req.on('end', function () {
// 解析参数
body = querystring.parse(body);
// 设置响应头部信息及编码
res.writeHead(200, {'Content-Type': 'text/html; charset=utf8'});
if(body.name && body.url) { // 输出提交的数据
res.write("网站名:" + body.name);
res.write("<br>");
res.write("网站 URL:" + body.url);
} else { // 输出表单
res.write(postHTML);
}
res.end();
});
}).listen(3000);
其效果如图:
将表单提交的数据
利用express框架获取表单内容
var express = require('express');
var app = express();
//将文件夹public设为express公开文件夹(express模块已经将fs方法至于其中,因此在设置公开文件夹时不需再引用fs模块)。
app.use(express.static('public'));
app.get('/index.html',function(req,res){
res.sendFile(_dirname+'/'+'index.html');
})
app.get('/process_get',function(req,res){
var 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(req,res){
var host = server.address().address
var port = server.address().port
console.log("应用实例,访问地址为 http://%s:%s", host, port);
});
html代码:
<html>
<body>
<form action="http://127.0.0.1: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" value="Submit">
</form>
</body>
</html>
效果如图:
express模块是一个web应用框架,他提供了很多强大的功能来更简单的创建web应用。
利用express及multer来实现文件的上传
multer模块主要处理表单文件的上传。
var express = require('express');
var multer = require('multer');
var app = express();
app.use(express.static('public'));
// 通过 filename 属性定制
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, '/web开发/测试/upload'); // 保存的路径,备注:需要自己创建
},
filename: function (req, file, cb) {
// 将保存文件名设置为 字段名 + 时间戳+后缀,比如 logo-1478521468943
cb(null, file.fieldname + '-' + Date.now()+'.jpg');
}
});
// 通过 storage 选项来对 上传行为 进行定制化
var upload = multer({ storage: storage })
//var upload = multer({dest : 'upload/' });
//var upload = multer({storage:storage});
app.get('/index',function(req,res){
res.send(_dirname+"/"+"index.html");
})
//single中的第二个参数代表可以接受几个文件,2代表可以接受两个文件
app.post('/upload',upload.single('pics,2'),function(req,res){
res.send("ok");
})
var server=app.listen(3030,function(){
var host = server.address().address
var port = server.address().port
console.log("应用实例,访问地址为 http://%s:%s", host, port)
})
上面这段代码可以实现文件的上传并将其放在规定的文件夹及其规律化的命名:
html代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<form action="/upload" method="post" enctype="multipart/form-data">
<!-- <span>first item</span><input type="text" name="first_item"><br/>
<span>second item</span><input type="text" name="second_item"><br/> -->
<span>file</span><input type="file" name="pics"><br/>
</be/>
<input type="submit" value="submit">
</form>
</body>
</html>
最后
终于把这个简单的文章写完了,这只是node的冰山一角,node还有很多模块及其方法,想要精通段时间内几乎是不可能的,后面还是要继续努力xio习啊!
引用