nodejs
** node.js是一个能在服务端运行js的开放源代码,跨平台js运行环境
node中采用Google开发V8引擎直接去运行js,使用事件驱动、非阻塞和异步i/o模型等技术来提高性能,可优化
应用程序的传输量和规模
nodejs用途:
web服务API
实时的多人游戏
基于web应用
提供命令行工具**
nodejs核心内置模块
http模块(http服务构建)
基本使用
//引入http模块
const http = require('http')
http.createServer((request,response)=>{
//获取请求的url
console.log(request.url)
//设置响应头
response.setHeader("Content-Type", "text/text;charset=utf-8")
//页面输出内容
response.write("你好啊!")
//结束响应
response.end()
}).listen(5000)//端口号
//supervisor服务器工具 如果想要修改代码自动刷新需要下载插件npm install -g supervisor,并且使用supervisor来启动js文件
//或者使用nodemon 下载npm install nodemon --global
// NodeJS获取POST请求
const http = require('http')
let app = http.createServer((req, res) => {
let postData = ''
req.on('data', chunk => {
postData += chunk.toString()
})
req.on('end', () => {
if (postData) {
res.setHeader('Content-type', 'application/json')
res.end(postData)
}
console.log(JSON.parse(postData))
})
})
app.listen(8000, () => {
console.log('running on 8000')
})
url模块
url.parse() 将一个url字符串解析并且返回一个url对象
url.format(urlObject) 对一个url对象进行格式化操作,返回一个url字符串
url.resolve(from,to) 返回一个’from/to’的字符串,相当于对路径进行拼接
基本使用
const url = require('url');
let api = "http://www.baidu.com?name=zhangsan&age=20";
let getValue = url.parse(api,true).query;
console.log(getValue)
path模块(路径操作)
const path = require('path');
console.log(path.extname())//可以获取后缀名
os模块(操作系统信息模块)
const os = require('os');
console.log(os.cups());//获取当前机器的CPU信息
console.log(os.totalmem());//memory(存储器)内存 以字节为单位
fs模块(文件操作)
** __dirname全局变量,保存的是当前文件所在文件夹的路径**
1.fs.stat 检测是文件还是目录
const fs=require('fs');
fs.stat('./html',(err,data)=>{
if(err){
console.log(err);
return;
}
console.log(`是文件:${data.isFile()}`);
console.log(`是目录:${data.isDirectory()}`);
})
2.fs.mkdir 创建目录
fs.mkdir('./css',(err)=>{
if(err){
console.log(err);
return;
}
console.log('创建成功!');
})
3.fs.writeFile 创建写入文件(如果文件已经存在,会替换文件)
fs.writeFile('./html/index.html','你好nodejs',(err)=>{
if(err){
console.log(err);
return;
}
console.log('创建写入文件成功')
})
4.fs.appendFile 追加文件
fs.appendFile('./html/index.html','body{color:red}',(err)=>{
if(err){
console.log(err);
return;
}
console.log('appendFile成功')
})
5.fs.readFile 读取文件
fs.readFile('./html/index.html',(err,data)=>{
//失败error为错误对象,data为undefined,成功error为null,data为读取到的数据
if(err){
console.log(err);
return;
}
console.log(data);//文件中存储的都是二进制数据,这里转换为16进制了
//需要通过toString()方法转换成string类型
})
6.fs.readdir 读取目录
fs.readdir('./html/index.html',(err,data)=>{
if(err){
console.log(err);
return;
}
console.log(data);//成功data会以数组形式返回目录下的文件及文件夹
})
7.fs.rename 重命名 ①重命名②移动文件
//重命名
fs.rename('./html/aaa.html','./html/index.html',(err)=>{
if(err){
console.log(err);
return;
}
console.log('重命名成功');
})
//移动文件
fs.rename('./css/index.html','./html/index.html',(err)=>{
if(err){
console.log(err);
return;
}
console.log('移动文件成功');
})
8.fs.rmdir 删除目录
fs.rmdir('./html',(err)=>{//注意:目录下没有文件才可以删除目录
if(err){
console.log(err);
return;
}
console.log('删除目录成功');
})
9.fs.unlink 删除文件
fs.unlink('./html/aaa.html',(err)=>{
if(err){
console.log(err);
return;
}
console.log('删除文件成功');
})
10.fs.createReadStream 从文件流中读取数据(引流方式读取文件)
const fs=require('fs');
var readStream=fs.createReadStream('./data/index.txt');
var count = 0;
var str = '';
readStream.on('data',(data)=>{
str+=data;
count++;
})
readStream.on('end',()=>{
console.log(str);
console.log(count);
})
readStream.on('error',(err)=>{
console.log(err);
})
11.fs.createWriteStream 写入文件(引流方式写入文件)
const fs=require('fs');
var str='';
for(var i=0; i<500;i++){
str+="我是数据库获取的数据,保存起来\n";//\n换行
}
var writeStream=fs.createWriteStream('./data/index.txt');
writeStream.write(str);
//标记写入完成
writeStream.end();
writeStream.on('finish',()=>{
console.log('写入完成');
})
fs.readFileSync 读取文件(同步方法)
fs.readFileSync('./html/index.html',(err,data)=>{
//失败error为错误对象,data为undefined,成功error为null,data为读取到的数据
if(err){
console.log(err);
return;
}
console.log(data);//文件中存储的都是二进制数据,这里转换为16进制了
//需要通过toString()方法转换成string类型
})
管道流(实现大文件的复制过程)
const fs=require('fs');
var readStream=fs.createReadStream('./demo01.zip');
var writeStream=fs.createWriteStream('./demo.zip');
readStream.pipe(writeStream);
CommonJS(nodejs)中自定义模块
1.我们可以把公共的功能抽离成一个单独的js文件作为一个模块,默认这个模块里面的方法或者属性,外面没办法访问。如果要让外部可以访问模块里面的方法或者属性,就必须在模块里面通过exports或者module.exports暴露属性或者方法
2.在需要使用这些模块的文件中,通过require的方式引入这个模块。这个时候就可以使用模块里面暴露的属性和方法
let obj={
get(){
console.log('get啦!')
},
set(){
console.log('set啦!')
}
}
//通过exports暴露的两种方式
module.exports = obj;
exports.get=obj.get;
nodejs新特性,ES7 async await的基本使用
async是“异步”的简写,而await可以认为是async wait的简写,async用于申明一个异步的function,而await用于等待一个异步方法执行完成
简单理解:async是让方法变成异步
await 是等待异步方法执行完成
返回一个promise
async function test(){
return new Promise((resolve,reject)=>{
setTimeout(function(){
let name='张三';
resolve(name);
},1000)
})
}
async function main(){
let data = await test();//获取异步方法里面的数据
console.log(data);
}
main();//你好nodejs!
Express框架
Express是一个基于nodejs的web应用开发框架,提供一系列强大的特性
扩展了web应用所需的基本功能,丰富了HTTP工具,可以快速搭建一个网站
安装:npm install express --save
基本使用:
const express = require('express');
const app = express();
app.get('/', function (req, res) {
res.send('hello world');
})
app.listen(3000,function(){
console.log("通过http://localhost:3000/来访问")
})
Express框架处理静态资源
//首先在本地创建static文件夹,并把静态文件放入
const express = require("express");
const app = express();
// app.use('/*', function (req, res, next) {
// console.log("我是指定的第一个中间件");
// next();
// });//中间件,每次请求之后,响应请求之前,中间件都会被使用
//中间件:完成特定功能的函数,一次请求可以使用多个中间件,通过多个中间件帮助完成一个复杂的功能
//第一个参数:对应的是一个路径,可以不写,代表的所有路径下,'/*'也代表所有路径,'/test'如果有特殊要求,写清楚指定路径即可
//第二个参数:回调函数,指定功能的代码段
//next()用于结束当前中间件,如果没有,程序会出现死循环的现象
// app.use('/*', function (req, res, next) {
// console.log("我是指定的第二个中间件");
// next();
// });
//express.static:express提供的中间件实现加载静态资源
app.use(express.static('static'));//在本地static文件通过url路径来加载静态资源
app.get('/', (req, res) => {
console.log("执行响应");
res.send('111');
}).listen(3000)
使用模板引擎
jade模板,安装:cnpm install jade
//配置jade.js
const express = require("express");
const app = express();
//对express进行设置,让框架识别模板
app.set('view engine', 'jade');
//设置模板的相对路径
app.set('views', __dirname + '/jade');
//加载静态资源
app.use(express.static('static'))
app.get('/', function (req, res) {
res.render('index', {})
}).listen(3000);
//创建jade文件夹,再创建index.jade文件
//基本使用
doctype html
html(lang='en')
head
meta(name="keywords",content="内容")
script(type="text/javascript")
//通过.来为style标签里面写属性
style.
h1{
color:red;
}
body
h1 内容
//如果使用tab就都使用tab,不能空格和tab混合使用
//jade的注释和js的注释一样
|text
//在纯文本前加一个|,显示为纯文本
//-在模板中使用js语句
-for(var i=0;i<3;i++)
div element#{i}
-var str='哈哈哈'
div=str
ejs模板,安装:cnpm install ejs
//配置ejs.js
const express = require('express');
const app = express();
app.set('view engine', 'ejs');
app.set('views', __dirname + '/ejs');
app.use(express.static('static'));
app.get('/', function (req, res) {
res.render('index', {
stu1: {
name: "张三",
sex: "男",
age: 20
}
})
}).listen(3000);
//创建ejs文件夹,再创建index.ejs文件
//基本使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>ejs模板</title>
</head>
<body>
<h1>内容</h1>
姓名:<%= stu1.name %>
性别:<%= stu1.sex %>
年龄:<%= stu1.age %>
</body>
art-template模板引擎,安装npm install art-template --save
//在浏览器中使用art-template模板
//创建HTML文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="box"></div>
hello {{name1}}
<script src="node_modules/art-template/lib/template-web.js"></script>
<script type="text/template" id="art">
<h2>{{name}}</h2>
<p>{{name}}的年龄是{{age}}</p>
<p>{{name}}的工作是{{job}}</p>
<button>{{count}}</button>
</script>
<script>
var html = tempalte('art', {
count: 0,
name: "张三",
age: 18,
job: 'web前端'
})
box.innerHTML = html;
</script>
</body>
</html>
//在nodejs中使用art-template模板
const art = require('art-template');
const fs = require('fs');
//读取html文件
fs.readFile('./使用art-template模板.html', (err, data) => {
if (err) {
console.log('404');
} else {
var html = art.render(data.toString(), {
name1: "张三"
})
console.log(html);
}
})
Express-art-template安装和基本使用
Express路由机制
基本使用:
const express = require('express');
const app = express();
app.get('/',function(req,res){
res.send('get请求')
})
app.post('/about',function(req,res){
res.send('post请求')
})
//根据对应的请求方式,get或者post,然后框架对路由进行管理
app.listen(3000);
bodyParser基本使用(中间件),安装:npm install body-parser
//获取post请求
const express = require('express');
const app = express();
const bodyParser = require('body-parser');
app.use(express.static('static'))//加载静态资源
//app.use引入bodyParser这个中间件,这样就可以使用这个中间件的功能
app.use(bodyParser.urlencoded({extended:false}));
app.use(bodyParser.json())
app.post('/post',function(req,res){
console.log(req.body);
res.send({
"msg":"post请求返回的数据",
"code":1
})
}).listen(3000);
nodejs其他常用模块
Buffer模块
在处理文件流的时候就需要使用buffer类型,buffer实际上就是用来保存二进制数据的容器,缓存区是buffer的中文译名
buffer模块是一个js和C++结合的模块
创建buffer对象
1.Buffer.alloc:创建一个指定长度的Buffer对象,并且可以对Buffer对象进行值得初始化设置
//参数1:希望Buffer对象的三种方式
//参数2:设置的初始化buffer的默认值,值都是16进制
var buf1 = Buffer.alloc(10,16);
console.log(buf1);
var buf2 = Buffer.alloc(10,'a');
console.log(buf2);
2.Buffer.allocUnsafe:创建的过程比Buffer.alloc效率高,因为它不会对Buffer数据进行重置,Buffer对象可能还包含了旧数据
var buf3 = Buffer.allocUnsafe(10);
console.log(buf3);
//对buffer对象进行重置
buf3.fill();
console.log(buf3);
buf3.write();
3.Buffer.from:传入的一个Buffer对象,数组或者字符串,返回一个新的Buffer
var buf4 = Buffer.from([1,2,3,4]);
console.log(buf4);
var buf5 = Buffer.from("test");
console.log(buf5);
var buf6 = Buffer.from(buf5);
console.log(buf6);
Buffer数据的写入和读取
buf.write:根据对应encoding编码把字符串写入到Buffer,如果字符串长度超过buf有效长度,多余部分不会写入
buf.toString:使用指定的encoding把数据变成字符串
//写入
var buf =new Buffer.alloc(7);
buf.write("哈哈哈");
console.log(buf);
console.log(buf.toString());
var buf1 = new Buffer.from("哈");
console.log(buf1);
//如果长度和写入长度不匹配,多余的长度不会做任何处理
//如果写入的内容长,对于的内容不会写入
//中文长度占3个buffer长度
Buffer转换json对象
buf.toJSON():把一个Buffer对象,转换成json对象
也可以直接使用JSON.stringify(),会隐式调用toJSON()方法
//转换为json对象
var buf = Buffer.from([1,2,3,4]);
console.log(buf.toJSON());
console.log(JSON.stringify(buf));
Buffer常用API
Buffer合并:concat(buf1,buf2)返回一个新的Buffer对象
//合并:类方法
var buf1 = Buffer.from("哈哈哈");
var buf2 = Buffer.from("Node.js");
var buf3 = Buffer.concat([buf1,buf2]);
console.log(buf3.toString());
Buffer比较:compare(buf1,buf2)长度比较,返回-1,0,1
//比较
var buf1 = Buffer.from("abcd");
var buf2 = Buffer.from("abc");
console.log(buf1.compare(buf2));
//0 表示比较长度相等 1调用放的Buffer对象长度大于另一个Buffer对象
//-1 调用方法的Buffer对象长度小于另一个Buffer对象
Buffer拷贝:buf2.copy(buf1)把buf2的内容拷贝到buf1上
//拷贝
var buf1 = Buffer.from("abcd");
var buf2 = Buffer.from("abc");
buf2.copy(buf1,2,1,3);
console.log(buf1.toString());
//参数2:buf1的起始拷贝位置,默认是0
//参数3:buf2开始拷贝位置 参数4:拷贝位置内容的长度
Buffer截取:buf.slice(0,2)返回一个新的Buffer对象
var buf1 = Buffer.from("abcd");
//参数2:代表结束的位置
console.log(buf1.slice(0,2).toString());
Buffer长度:buf.length()当前Buffer对象长度
var buf1 = Buffer.from("abcd");
console.log(buf1.length);
var buf = new Buffer.alloc(7);
var len = buf.write("哈哈哈");
console.log(len);
events事件模块
Nodejs使用事件驱动,events事件模块就是帮助nodejs来处理事件,对事件进行监听
事件处理流程:
监听事件addListener()给事件添加一个事件监听,在某个情况下会触发该事件
分发事件emit()触发指定事件
监听事件个数:查询指定事件有多少个监听函数
事件监听程序的执行顺序
当同一个事件绑定了多个监听器的时候,程序就按照代码写的顺序由上至下执行
如果事件同时绑定超过了10个监听器,nodejs会有一个警告,可以通过setMaxListeners去设置最多监听器个数
移除监听和自定义事件监听
移除监听removeListener移除指定的事件监听
自定义事件监听:通过继承EventEmitter类实现一个自定义事件监听
//引入events模块
const events = require('events');
//创建一个eventEmitter对象
const eventEmitter = new events.EventEmitter();
//添加事件
//参数1:事件名
//参数2:函数
//eventEmitter.addListener('test',function(){
// console.log('test事件被触发')
//})
//事件下发:通过指定的事件名,找到对应事件名
//eventEmitter.emit('test')
var timer = setInterval(function(){
var random = parseInt(Math.random()*100);
console.log(random);
//如果大于95,认为当前程序有风险,需要终止
if(random>95){
eventEmitter.emit('random')
}
},500)
eventEmitter.on("random",function(){
//清除定时器
clearInterval(timer);
console.log("random事件被触发,定时器终止")
})
console.log(eventEmitter.listenerCount('random'));
//移除事件监听
eventEmitter.addListener("test",cb);
function cb(a){
console.log("test事件被调用"+a)
}
eventEmitter.emit("test",100)
eventEmitter.removeListener("test",cb);
console.log(eventEmitter.listenerCount("test"))
//自定义事件监听
const events = require('events');
//js的使用工具,丰富了js的功能
const util = require('util');
//先实现一个自定义的构造函数
function BaseEmitter(){
this.emitter =events.EventEmitter();
}
//BaseEmitter继承events.Emitter
//参数1代表子类
//参数2代表父类
util.inherits(BaseEmitter,events.EventEmitter)
//实现addListener功能,添加监听器
BaseEmitter.prototype.addEvent = function (eventName,cb){
this.emitter.addListener(eventName,cb);
}
//实现emit功能
BaseEmitter.prototype.emitEvent =function (eventName,arg){
this.emitter.emit(eventName,arg)
}
var base = new BaseEmitter();
base.addEvent("test",function(a){
console.log("自定义事件监听被调用"+a)
})
base.emitEvent("test","测试");