一. Node.js是一个可以让javascript运行在服务器端的平台;
node.js是基于chrome v8引擎开发的运行javascript的平台
在计算机世界里,只有1和0(二进制),浏览器能够解析我们的代码是因为浏览器内嵌解析代码的机制,
将我们的代码解析成0和1构成的编码。
使得JavaScript即能写前端又能写服务端
(node.js 是common.js规范的实现者,所以他的引用模块用 require,暴露接口用module.exports);
Node使用Module模块去划分不同的功能,以简化应用的开发。
注意:
?①:node中不存在跨域(因为产生跨域的原因是浏览器的同源策略,node是一个基于chrome v8引擎的一个可以让javascript运行的环境,它与浏览器没有关联,所以不存在跨域)
?②:在node中,回调函数都有一个规范,错误优先的原则,回调函数的第一个参数都是err,表示是不是错误,默认的都是null,没有错误。
(err) => {
if (err) throw err;
});
二。模块分为三种:①内置模块;②自定义模块;③第三方插件(使用前,需要下载第三方插件);
①第三方模块的应用:
♦ 例如:request(request的模块是用来做数据请求的);// http模块中http.get 和http.request也可以用来做数据请求
①引入模块
const request=require("request");
request.get('http://api.douban.com/v2/movie/in_theaters', (err, response, body) => {
if (!err) {
// 这里的err是报错,response:是全面的信息,body:大多数情况下body里面的数据是我们想要的数据, 这里的得到的数据的类型是字符串
console.log(body);//这里的body的数据类型为字符串
/*{"success":"1",
"result": {"status":"ALREADY_ATT","par":"110101","idcard":"110101199001011114","born":"1990年01月01日","sex":"男","att":"北京市 东城区 ","postno":"100000","areano":"010","style_simcall":"中国,北京","style_citynm":"中华人民共和国,北京市"}}
console.log(JSON.parse(body));
// { success: '1',
result:
{ status: 'ALREADY_ATT',
par: '110101',
idcard: '110101199001011114',
born: '1990年01月01日',
sex: '男',
att: '北京市 东城区 ',
postno: '100000',
areano: '010',
style_simcall: '中国,北京',
style_citynm: '中华人民共和国,北京市' } }
} else {
console.log(err);
}
})*/
②自定义模块的应用:
首先我们要定义一个模块(创建一个js文件);`
var x = 5;
var addX = function (value) {
return value + x;
};
module.exports.x = x;//暴露模块(这里是直接暴露)
也可以这么写{module.exports.x = x},这种情况写,对应的模块的引入也要做相应的改变
module.exports.addX = addX;
简写:module.exports={
x,//属性名与属性值同名,可以省略属性值
addx
}
假设上面的代码是我们定义的一个名为example.js的文件的内容
我们在同目录下的js文件内要引入这个自定义的模块
var custom =require( './example.js' )//这里要注意路径的写法,同级目录下要写 ./
var {custom}=require('./example.js')
console.log(custom.x);
console.log(custom.addX(1));
③内置模块
node.js的内置模块就是node本身提供的模块,不用下载,直接使用require引入就可以使用这些模块的方法
常用的内置模块(api ):url,QueryString ,HTTP ,events,Stream ,fs:文件的读写
内置模块—fs(文件系统):读写文件 fs` 模块提供了一个 API用于以与文件系统进行交互
const fs=require("fs");
fs.readdir(path[,options],callback);
//读取文件夹的时候,回调函数中会有两个参数,一个是错误,另一个就是读取的文件
//如果 options 是一个字符串,则指定字符编码。 如果 encoding 设为 'buffer',则返回的文件名是 Buffer,可以定义为 utf8。
fs.readdir("./test",(err,file)=>{
console.log(err);
console.log(file); // 文件夹中的文件,以数组的形式存放
?fs .readFile('./1.txt',(err,docs)=>{//buffer代表二进制的输出
console.log(docs);
//<Buffer e6 88 91 e6 98 af e6 b5 8b e8 af 95 e5 86 85 e7 bd ae e6 a8 a1 e5 9d 97 66 73 e7 9a 84 e6 96 87 e4 bb b6>
});
?fs .readFile('./1.txt','utf8',(err,docs)=>{
console.log(docs);
//我是测试内置模块fs的文件
});
?fs .readFile('./1.txt','utf8',(err,docs)=>{
console.log(docs.toString());
//我是测试内置模块fs的文件
});
内置模块–querystring(是做字符串格式化)
使用api:
escape?对中文进行编码;
unescape:对编码的字符串进行解码成对应的中文
parse : 将字符串转为对象
stringify: 将对象转为字符串 【 编码 】
const qs = require( 'querystring' );
?:parse
var str = 'https://fanyi.baidu.com/?aldtype=16047#en/zh/querystring';
var str1='http://www.baidu.com/home?a=1&b=2#c=3';
const str3 = '李爽';
const str4 = "name=李爽";
console.log(qs.parse(str));
console.log(qs.parse(str1));
//在当前路径下,在终端执行querstring.js这个文件:node querystring.js 得到的结果为
{ 'https://fanyi.baidu.com/?aldtype': '16047#en/zh/querystring' }
{ 'http://www.baidu.com/home?a': '1', b: '2#c=3' }
console.log(qs.parse(str3));
// { '格瑞': '' }
//由于代码的开发语言是英语,所以我们在有中文的情况下,需要将中文进行编码解码的操作
?escape与unescape
console.log(qs.escape(str4));
//name%3D%E6%9D%8E%E7%88%BD'
console.log(qs.unescape('name%3D%E6%9D%8E%E7%88%BD'));
//name=格瑞
?stringify
const obj = {
name:'lishaung',
sex:'girl'
}
console.log(qs.stringify(obj));
//name=lishaung&sex=girl
内置模块—stream 流 模块(这里的流指的是数据流,指的是数据是分片传输,一股一股的 chunk)
几乎所有的 Node.js 应用都在某种程度上使用了流。
流(stream)是 Node.js 中处理流式数据的抽象接口。 stream
模块用于构建实现了流接口的对象。
Node.js 提供了多种流对象。 例如,HTTP 服务器的请求和 process.stdout
都是流的实例。
流可以是可读的、可写的、或者可读可写的。 所有的流都是 EventEmitter
的实例。
数据可以实现非阻塞
? gulp 就是流式操作
下面是一个例子,使用流实现了打包压缩包-----内置模块–zlib
const fs = require ( 'fs' );
const zlib = require( 'zlib' );
const gzip = zlib.createGzip();//创建压缩包对象
假设此时我们创建了一个 1.txt 的文件,在zlib.js内进行nodejs文件的编写
const inp = fs.createReadStream('./1.txt');//读取1.txt文件
const out = fs.createWriteStream('./1.txt.gz');
inp.pipe(gzip).pipe(out);
在终端执行文件
内置模块—http–get请求
const http = require( 'http' )
http.get('http://api.k780.com/?app=life.time&appkey=10003&sign=b59bc3ef6191eb9f747dd4e83c99f2a4&format=json', (res) => {
const { statusCode } = res; // 获取请求状态码 200 301 302 303 304 404 500
const contentType = res.headers['content-type']; // 获取请求类型数据类型
// json数据的content-type 'content-type': 'application/json'
let error;
if (statusCode !== 200) { // 如果状态码不是200 ,输出报错信息
error = new Error('Request Failed.\n' +
`Status Code: ${statusCode}`);
} else if (!/^application\/json/.test(contentType)) {
error = new Error('Invalid content-type.\n' +
`Expected application/json but received ${contentType}`);
}
if (error) { // 如果报错了,将报错信息存入日志
console.error(error.message);
// consume response data to free up memory
res.resume();
return;
}
res.setEncoding('utf8'); // 字符编码
let rawData = '';
res.on('data', (chunk) => { rawData += chunk; }); // 通过data事件拼接数据流
res.on('end', () => { // 获取数据结束了
try { // 高级编程语法 捕获错误信息
console.log( rawData );
} catch (e) {
console.error(e.message);
}
});
}).on('error', (e) => {
console.error(`Got error: ${e.message}`);
});
执行后输出的结果:
/* { success: '1',
result:
{ timestamp: '1563283574',
datetime_1: '2019-07-16 21:26:14',
datetime_2: '2019年07月16日 21时26分14秒',
week_1: '2',
week_2: '星期二',
week_3: '周二',
week_4: 'Tuesday' } } */