1.querystring
querystring: --- > qs npm i qs ==> qs:parse/stringify第三方插件,只有一个参数
JSON.parse 字符串转对象
JSON.stringify 对象转字符串qs.parse() --- decode
qs.stringify() --- encode
parse/stringify(str/json,第一次切割符号,第二次切割符号)
qs.escape() 编码 encodeURIComponent
qs.unescape() 解码 decodeURIComponent
qs.decode 对象转字符串
qs.encode 字符串转对象
1.qs.parse(); qs.stringify();
qs.js
var qs = require("querystring");var str = "a=12&b=5"//{a:12,b:5}var json = qs.parse(str);console.log(json);console.log(qs.stringify(json));
res:
my@my-THINK MINGW64 /d/workspace/7.11$ node qs{ a: '12', b: '5' }a=12&b=5
qs3.js
//qs.parse/stringify(str,第一次切割的符号,第二次切割的符号)
var qs = require("querystring");var str = "a|12=b|5=age|20";//qs.parse/stringify(str,第一次切割的符号,第二次切割的符号)var json = qs.parse(str,"=","|");console.log(json);console.log(qs.stringify(json,"=","|"));
res
my@my-THINK MINGW64 /d/workspace/7.11$ node qs3{ a: '12', b: '5', age: '20' }a|12=b|5=age|20
qs4.js
引入第三方模块 npm i qs
//qs.parse/stringify(str)
后面不能跟分隔符号var qs = require("qs");var str = "a=12&b=5";var json = qs.parse(str);console.log(json);console.log((qs.stringify(json)));
res:
my@my-THINK MINGW64 /d/workspace/7.11$ node qs4{ a: '12', b: '5' }a=12&b=5
2.qs.escape();编码 qs.unescape();解码
qs2.js
var qs = require("querystring");var str = "aaa中文";var code = encodeURIComponent(str);console.log(code);console.log(decodeURIComponent(code));console.log("----------------------");var code = qs.escape(str);console.log(code);console.log(qs.unescape(code));
res:
my@my-THINK MINGW64 /d/workspace/7.11$ node qs2aaa%E4%B8%AD%E6%96%87aaa中文----------------------aaa%E4%B8%AD%E6%96%87aaa中文
3.
qs.encode()//转字符串
qs.decode()//转对象 parse
qs5.js
var qs = require("querystring");//encode|decode//var str = "aaa中文";var str = "a=12&b=5";var str = {a:12,b:5};var code = qs.encode(str);//转字符串 stringifyconsole.log(code);console.log(qs.decode(code));//转对象 parse
res:
my@my-THINK MINGW64 /d/workspace/7.11$ node qs5a=12&b=5{ a: '12', b: '5' }
2.url
url:
url.parse()--->urlObj url.format(urlObj)--> strUrl url.resolve(from, to);URLSearchParams new URLSearchParams();
地址组成:http://www.baidu.com:80/index.html?user=aaa&pass=123#page6http:// www.baidu.com :80 /index.html ?user=aaa&pass=123 #page6 协议 域名 端口 路径(资源地址) 数据 锚点 哈希hashlocationUrl { protocol: 'http:', slashes: true, auth: null, host: 'www.baidu.com:80', port: '80', hostname: 'www.baidu.com', hash: '#page6', search: '?user=aaa&pass=123', query: 'user=aaa&pass=123', pathname: '/index.html', path: '/index.html?user=aaa&pass=123', href: 'http://www.baidu.com:80/index.html?user=aaa&pass=123#page6' } URL { href: 'http://www.baidu.com/index.html?user=aaa&pass=123#page6', origin: 'http://www.baidu.com', protocol: 'http:', username: '', password: '', host: 'www.baidu.com', hostname: 'www.baidu.com', port: '', pathname: '/index.html', search: '?user=aaa&pass=123', searchParams: URLSearchParams { 'user' => 'aaa', 'pass' => '123'}, hash: '#page6' }
1.
.parse()转成对象
.format()转成字符串
url1.js
var modUrl = require("url");var url = "http://www.baidu.com:80/index.html?user=aaa&pass=123#page6";var urlObj = modUrl.parse(url);console.log(1,urlObj);console.log(2,modUrl.format(urlObj));
res:
my@my-THINK MINGW64 /d/workspace/7.11$ node url11 Url { protocol: 'http:', slashes: true, auth: null, host: 'www.baidu.com:80', port: '80', hostname: 'www.baidu.com', hash: '#page6', search: '?user=aaa&pass=123', query: 'user=aaa&pass=123', pathname: '/index.html', path: '/index.html?user=aaa&pass=123', href: 'http://www.baidu.com:80/index.html?user=aaa&pass=123#page6' }2 'http://www.baidu.com:80/index.html?user=aaa&pass=123#page6'
url2.js
var modUrl = require("url");var url = "http://www.baidu.com:9000/index.html?user=aaa&pass=123#page6";console.log(1,new modUrl.Url(url));console.log(2,new modUrl.URL(url));
res:
my@my-THINK MINGW64 /d/workspace/7.11$ node url21 Url { protocol: null, slashes: null, auth: null, host: null, port: null, hostname: null, hash: null, search: null, query: null, pathname: null, path: null, href: null }2 URL { href: 'http://www.baidu.com:9000/index.html?user=aaa&pass=123#page6', origin: 'http://www.baidu.com:9000', protocol: 'http:', username: '', password: '', host: 'www.baidu.com:9000', hostname: 'www.baidu.com', port: '9000', pathname: '/index.html', search: '?user=aaa&pass=123', searchParams: URLSearchParams { 'user' => 'aaa', 'pass' => '123' }, hash: '#page6' }
url3.js
.resolve(),替换路径
var modUrl = require("url");console.log(modUrl.resolve('http://localhost:9000/login', 'index')); console.log(modUrl.resolve('http://localhost:9000/login', '/index')); console.log(modUrl.resolve('http://localhost:9000/users/login', 'index')); //不加/只替换最后一个相对路径console.log(modUrl.resolve('http://localhost:9000/users/login', '/index')); //加/替换绝对路径
res:
my@my-THINK MINGW64 /d/workspace/7.11$ node url3http://localhost:9000/indexhttp://localhost:9000/indexhttp://localhost:9000/users/indexhttp://localhost:9000/index
url4.js
URLSearchParams
new URLSearchParams();var modUrl = require("url");var params = new modUrl.URLSearchParams();console.log(params);params.append("user","aaa");params.append("pass","123");//append添加数据// user=aaa&pass=123console.log(params);console.log(params.toString());
res:
my@my-THINK MINGW64 /d/workspace/7.11$ node url4URLSearchParams {}URLSearchParams { 'user' => 'aaa', 'pass' => '123' }user=aaa&pass=123
url5.js
//node 10以上,才可以var params = new URLSearchParams();params.append("user","aaa");params.append("pass","123");// user=aaa&pass=123console.log(params.toString());
res:
my@my-THINK MINGW64 /d/workspace/7.11$ node url5user=aaa&pass=123
3.path
path:
path.parse(path)
path.format(pathObject)
path.basename(path)
path.dirname(path) 路径 path.extname(path)
path.join() 相对路径 路径拼接
path.relative() 获取的相对路径 路线图 path.resolve() 绝对路径 路径拼接 碰到绝对路径 会替换
__dirname 绝对路径
__filename 绝对地址包含文件名
global 全集对象 相当于 window
path1.js
var path = require("path");//win: \ linux /var str = "D:\\wamp64\\www\\20180711\\path.js"; //window要用双斜线,向右撇var str = "D:/wamp64/www/20180711/path.js";var pathObj = path.parse(str);console.log(pathObj);//字符串转对象console.log(path.format(pathObj));//对象转字符串
res:
my@my-THINK MINGW64 /d/workspace/7.11$ node path1{ root: 'D:/', dir: 'D:/wamp64/www/20180711', base: 'path.js', ext: '.js', name: 'path' }D:/wamp64/www/20180711\path.js
path2.js
var path = require("path");var str = "D:/wamp64/www/20180711/path.js";console.log(path.parse(str));console.log("--------------------------");console.log(path.basename(str));//文件名console.log(path.dirname(str)); //路径console.log(path.extname(str));//文件后缀 带点console.log("--------------------------");console.log(__dirname);console.log(__filename);
res:
my@my-THINK MINGW64 /d/workspace/7.11$ node path2{ root: 'D:/', dir: 'D:/wamp64/www/20180711', base: 'path.js', ext: '.js', name: 'path' }--------------------------path.jsD:/wamp64/www/20180711.js--------------------------D:\workspace\7.11D:\workspace\7.11\path2.js
path31.js
var path = require("path");console.log("www"+"/index.html");//只是拼接console.log(path.join("www","/index.html"));console.log(path.join("www","/index.html"));//自动去除多余的/console.log(path.join("www","index.html"));//自动添加/
res:
my@my-THINK MINGW64 /d/workspace/7.11$ node path31www/index.htmlwww\index.htmlwww\index.htmlwww\index.html
path32.js
var path = require("path");console.log("www"+"/index.html");console.log(path.join("\\a","b","c"));console.log(path.join("/a","b","c"));console.log(path.join("a","/b","../c")); //../返回上级目录
res:
my@my-THINK MINGW64 /d/workspace/7.11$ node path32www/index.html\a\b\c\a\b\ca\c
path33.js
var path = require("path");console.log(path.relative('/data/orandea/test/aaa', '/data/orandea/impl/bbb'));console.log(path.relative('C:\\orandea\\test\\aaa', 'C:\\orandea\\impl\\bbb'));
res:
my@my-THINK MINGW64 /d/workspace/7.11$ node path33..\..\impl\bbb..\..\impl\bbb
path34.js
var path = require("path");/* resolve返回绝对路径,参数前不加/,在后面添加,加/直接替换全部 */console.log(path.resolve("a","b","c"));console.log(path.resolve("a","/b","/c"));console.log(path.resolve("a/b/c","../d","../e"));
res:
my@my-THINK MINGW64 /d/workspace/7.11$ node path34D:\workspace\7.11\a\b\cD:\cD:\workspace\7.11\a\b\e
4.Buffer
Buffer 二进制流
操作方式和字符串类似16进制 0-F
"a".chatCodeAt(0).toString(16); ascii:97 hex:61
97: a (ASCII)
String.fromCharCode(code);//ASCII转字符
中文的范围 4e00 - 9fa5
\u4e00(直接转成中文) 0X4e00(转成十进制)hex: 16进制
Buffer.from(...); new Buffer(废弃)
buf1.js
var str = "abc";//var buf = new Buffer(str);var buf = Buffer.from(str);console.log(buf);//16进制 中文的范围 4e00 - 9fa5console.log("a".charCodeAt(0).toString(16));
res:
$ node buf161
buf2.js
const buf = Buffer.from('abc', 'ascii');console.log(buf);console.log(buf.toString('hex'));console.log(buf.toString('base64'));
res:
$ node buf2616263YWJj
buf3.js
const buf = Buffer.from([1, 2, 3]);console.log(buf);for(var i = 0; i < buf.length; i++){ console.log(buf[i]); }// Prints:// 1// 2// 3for (const b of buf) { console.log(b);}
res:
$ node buf3123123
buf4.js
var buf = Buffer.from([0x61, 0x62, 0x63]);console.log(buf.toString());var buf = Buffer.from("abc");console.log(buf.toString());
res:
$ node buf4abcabc
buf42.js
var buf1 = Buffer.from("abc"); //var buf2 = Buffer.from(buf1);var buf2 = Buffer.from("abc");console.log(buf1.toString(),buf2.toString());//abc abcconsole.log(buf1 == buf2);//falseconsole.log(buf1 === buf2);//falseconsole.log(buf1.toString() == buf2.toString());//trueconsole.log(Buffer.compare(buf1, buf2));//0 , 相同为0,不同为-1
res:
$ node buf42abc abcfalsefalsetrue0
buf5.js
var str = "abc中文";var buf = Buffer.from(str); console.log(buf);console.log(str.length);console.log(buf.length);console.log(Buffer.byteLength(buf));
res:
$ node buf5599
buf6.js
var str = "abc";var arr = [];for(var i = 0; i < str.length; i++){ arr.push(Buffer.from(str[i]));//61 62 62 arr[buf1,buf2,buf3]}console.log(arr);console.log(Buffer.concat(arr));
res:
$ node buf6[, , ]
buf7.js
Buffer.isBuffer() 判断是否是Buffer
var str = "abc";console.log(Buffer.isBuffer(str));var buf = Buffer.from(str);console.log(Buffer.isBuffer(buf));
res:
$ node buf7falsetrue
buf8.js
.equals()判断buffer是否相等
const buf1 = Buffer.from('ABC');const buf2 = Buffer.from('414243', 'hex');//ABCconst buf3 = Buffer.from('ABCD');// 输出: trueconsole.log(buf1.equals(buf2));// 输出: falseconsole.log(buf1.equals(buf3));
res:
$ node buf8truefalse
buf9.js
/*buf.includes/indexOf*/var buf = Buffer.from('abcdef');console.log(buf.includes("def"));//是否包含"def"console.log(buf.indexOf("def"));//是否包含"def",有的话输出开始下标,没有的话输出-1;
res:
$ node buf9true3
buf10.js
/*buf.includes/indexOf*/var buf = Buffer.from('abcdef');console.log(buf.keys());console.log(buf.values());//buf是一个对象,需循环输出key和valueconsole.log("------keys------------");for(var n of buf.keys()){ console.log(n);}console.log("------values------------");for(var n of buf.values()){ console.log(n,String.fromCharCode(n));}
res:
$ node buf10{}{}------keys------------012345------values------------97 'a'98 'b'99 'c'100 'd'101 'e'102 'f'
5.events
evt1.js
var EventEmitter = require("events");console.log(EventEmitter == EventEmitter.EventEmitter);
res:
$ node evt1true
evt21.js
var EventEmitter = require("events");var ev = new EventEmitter();console.log(ev.on == ev.addListener);//添加事件//addListener/onev.on("sum",function(a,b){ console.log("sum:",a+b); });ev.addListener("abc",function(){ console.log("abc:"); });//触发console.log(1,ev.emit("sum",12,5));console.log(2,ev.emit("abc"));
res:
$ node evt21truesum: 171 trueabc:2 true
evt22.js
var EventEmitter = require("events");var ev = new EventEmitter.EventEmitter();console.log(ev.on == ev.addListener);//添加事件//addListener/onev.on("sum",function(a,b){ console.log("sum:",a+b); });ev.addListener("abc",function(){ console.log("abc:"); });//触发console.log(1,ev.emit("sum",12,5));console.log(2,ev.emit("abc"));
res:
$ node evt22truesum: 171 trueabc:2 true
evt3.js
var EventEmitter = require("events");var ev = new EventEmitter();console.log(1,ev.on == ev.addListener);//添加事件ev.prependListener("abc",function(){ console.log(2,"abc:"); });//触发console.log(3,ev.emit("abc"));
res:
$ node evt31 true2 'abc:'3 true
6.fs 文件目录
文件
读写
fs.readFile 读
fs.writeFile 写 fs.appendFile 添加内容 fs.unlink 删除 fs.copyFile 复制
目录
fs.mkdir 创建
fs.rmdir 删除 fs.readdir 读
状态
文件或者目录是否存在
fs.exists 废弃
fs.access
判断是否是文件或者目录
fs.stat(path,function(stats){ stats.isFile()/isDirectory()})
监听
fs.watch(filename[, options][, listener])
fs.watchFile(filename[, options], listener)
fs1.js
写比读先执行
var fs = require("fs");//readFile/Sync//读fs.readFile("a.txt",function(err,data){ console.log(1,err,data); });//写,找到a.txt没有的话创建,添加"aaa"到a.txtfs.writeFile("a.txt","bbb",function(err){ console.log(2,err); //返回null,表示没有错误});
res:
$ node fs12 null1 null
fs2.js
//copyFile("源文件","目标文件",回调函数)
var fs = require("fs");//拷贝 1、先读 2、再写//读/*fs.readFile("a.txt",function(err,data){ if(err){ console.log("读取文件失败"); } else { //写 fs.writeFile("b.txt",data,function(err){ if(err){ console.log("拷贝失败"); } else { console.log("拷贝成功"); } }); } });*///copyFile("源文件","目标文件",回调函数)fs.copyFile("a.txt","b.txt",function(err){ if(err){ console.log("拷贝失败"); } else { console.log("拷贝成功"); } });
rse:
$ node fs2拷贝成功
fs3.js
//appendFile 创建文件或者追加
var fs = require("fs");//appendFile 创建文件或者追加fs.appendFile("b.txt","append",function(err){ console.log(err);});
res:
$ node fs3null
fs4.js
unlink 删除文件 不能删除目录
var fs = require("fs");//unlink 删除文件 不能删除目录fs.unlink("b.txt",function(err){ console.log(err);});
res:
$ node fs4null
fs51.js
//fs.mkdir()创建目录
var fs = require("fs");//创建目录fs.mkdir("abc", function(err){ console.log(err); });
res:
$ node fs51null
fs52.js
//删除目录fs.rmdir
var fs = require("fs");//删除目录fs.rmdir("abc", function(err){ console.log(err); });
res:
$ node fs52null
fs53.js
//读取目录fs.readdir
var fs = require("fs");//读取目录fs.readdir("abc", function(err,res){ console.log(err,res); });
res:
$ node fs53null [ 'youarebeautiful' ]
fs61.js
fs.exists
//判断文件和目录 //文件状态 文件、目录是否存在 是文件 还是目录var fs = require("fs");//判断文件和目录//文件状态 文件、目录是否存在 是文件 还是目录fs.exists("abcd", (exists) => { console.log(exists);});
res:
$ node fs61true
fs62.js
fs.access
var fs = require("fs");//判断文件和目录//文件状态 文件、目录是否存在 是文件 还是目录fs.access("a.txt", (err) => { console.log(err);});
res:
$ node fs62null
fs63.js
var fs = require("fs");//判断文件和目录//文件状态 文件、目录是否存在 是文件 还是目录fs.stat("abc", (err,stats) => { //stats.isDirectory()是否是目录/stats.isFile()是否是文件 console.log(err,stats.isFile(),stats.isDirectory());});
res:
$ node fs63null false true
fs71.js
var fs = require("fs");//可以监听文件和目录//监听有范围限制 只有一层fs.watch("a.txt", (eventType, filename) => { console.log(`事件类型是: ${eventType}-----${filename}`);});
res:
$ node fs71事件类型是: change-----a.txt事件类型是: change-----a.txt
fs72.js
var fs = require("fs");//可以监听文件 目录 有延迟 目录的文件的修改监听不到 最好用来监听文件fs.watchFile("abc", (curr, prev) => { /*console.log(curr); console.log(prev);*/ console.log(curr.mtime);});/*Stats { dev: 4145068239, mode: 16822, nlink: 1, uid: 0, gid: 0, rdev: 0, blksize: undefined, ino: 844424930155958, size: 0, blocks: undefined, atimeMs: 1531312004235.5886, mtimeMs: 1531312004235.5886, ctimeMs: 1531312004235.5886, birthtimeMs: 1531311081220.7952, atime: 2018-07-11T12:26:44.236Z, mtime: 2018-07-11T12:26:44.236Z, ctime: 2018-07-11T12:26:44.236Z, birthtime: 2018-07-11T12:11:21.221Z } */
res:
$ node fs722018-07-11T12:24:44.050Z
7.流stream
流stream
输入流、输出流
var rs = fs.createReadStream("src");
var ws = fs.createWriteStream("dist");管道pipe
rs.pipe(ws);
拆解:
//一边读一边写
rs.on("data",function(data){ ws.wrtie(data);});rs.on("end",function(data){ ws.end(fn);});
rs.on("error",function(){...})
ws.on("error",function(){...}) ---gzip:
1、const zlib = require('zlib');
2、必须设置一个头:
res.writeHead(200, { 'content-encoding': 'gzip' });
3、通过管道
rs.pipe(zlib.createGzip()).pipe(res);
stream1.js
var fs = require("fs");//输入流 输出var rs = fs.createReadStream("a.txt");var ws = fs.createWriteStream("b.txt");//管道 pipers.pipe(ws);将a.txt中的内容一步一步写入b.txt
res:
$ node stream1
stream2.js
var fs = require("fs");//输入流var rs = fs.createReadStream("a.txt");rs.on("data",function(data){ console.log(data); });rs.on("end",function(){ console.log("读完了"); });rs.on("error",function(){ console.log("读取文件失败"); });
res:
$ node stream2读完了
stream3.js
var fs = require("fs");var ws = fs.createWriteStream("b.txt");ws.write("abc",function(){ console.log("write完了"); });ws.end("end",function(){ console.log("end写完了"); });
res:
$ node stream3write完了end写完了
stream4.js
var fs = require("fs");var rs = fs.createReadStream("a.txt");var ws = fs.createWriteStream("b.txt");rs.on("data",function(data){ ws.write(data); });rs.on("end",function(){ console.log("读完了"); ws.end(function(){ console.log("写完了"); });});
res:
$ node stream4读完了写完了
server.js
前面的服务器可以写成流
大文件可以压缩var http = require("http");var fs = require("fs");var zlib = require("zlib");var server = http.createServer(function(req,res){ var url = req.url; if(url == "/favicon.ico") return; /*fs.readFile("www"+url,function(err,data){ if(err){ res.end("404"); } else { res.end(data); } });*/ res.writeHead(200, { 'content-encoding': 'gzip' }); var rs = fs.createReadStream("www"+url); rs.pipe(zlib.createGzip()).pipe(res); });server.listen(9000);
完整服务器代码:
server.js
var http = require("http");var fs = require("fs");var zlib = require("zlib");var modUrl = require("url");var qs = require("querystring");var users = {aaa:123};var server = http.createServer(function(req,res){ var url = req.url; var str = ""; req.on("data",function(data){ str += data; }) req.on("end",function(){ var urlObj = modUrl.parse(url,true); url = urlObj.pathname; var GET = urlObj.query; var POST = qs.parse(str); var params = req.method == "POST" ? POST : GET; var username = params.user; var password = params.pass; if(url == "/login"){ if(users[username]){ if(users[username] == password){ res.end(JSON.stringify({"error":1,"msg":"登陆成功"})); }else{ res.end(JSON.stringify({"error":0,"msg":"用户名或者密码错误"})); } }else{ res.end(JSON.stringify({"error":0,"msg":"用户名或者密码错误"})); } }else if(url == "/reg"){ if(users[username]){ res.end(JSON.stringify({"error":0,"msg":"用户名已存在"})); }else{ users[username] = password; res.end(JSON.stringify({"error":1,"msg":"注册成功"})); } }else if(url == "/favicon.ico") { return; }else{ res.writeHead(200, { 'content-encoding': 'gzip' }); var rs = fs.createReadStream("www"+url); rs.pipe(zlib.createGzip()).pipe(res); console.log(res); } }) });server.listen("9000",function(){ console.log("服务器已打开!");})
user.html
用户名: 密码: