网址
-
官网
- https://nodejs.org
-
中文文档
- http://www.nodeclass.com/api/node.html
nodejs
什么是nodejs:
是构建在 Chromes V8 引擎上 js 的运行环境,可以解析javaScript 代码。
javaScript 可以脱离浏览器运行,归功于node.js
事件驱动,非阻塞I/O 模型 (异步)
nodejs npm 是世界上最大的开源生态系统 javaScript 绝大多数包存放在npm 上
-
Node.js可以做什么
没有 BOM DOM
就是没有window 和 document
web 服务器后台
命令行工具
npm (node)
hexo (node)
git (c)
-
B/S 编程模型
Browser - Server
任何服务器端技术都是BS编程模型都是一样,和语言无关、
Node 只是作为我们学习BS的工具而已
-
模块化编程
RequireJS
SeaJS
-
Node常用的API
-
异步编程
回调函数
Promise
async
generator
-
Ecmascript 6
-
浏览器中的javaScript 没有文件操作=能力的e
-
在node 中 的JavaScript具有文件操作能力的
- 新建一个domo
- npm init -y
- npm i mongoose
- …
npm
-
创建node_mudules 文件
npm init -y
设置默认 node_moduo路径
-
查看当亲路径
npm config get prefix
-
设置默路径
C:\Users\小毅\AppData\Roaming\npm
新建项目
- npm init -y
- npm install express
- node app.js
文件操作
-
文件操作路径
//在文件操作中的相对路径 ./data/a.txt 相对于当前目录 data/a.txt 相对于当前目录 /data/a.txt 绝对路劲,当前文件模块所处的磁盘根目录 c:/xx/xxx... 绝对路径
-
模块操作路径
// 相对路径 require('./data/app.js') // 如果忽略了 . 则是磁盘根目录 require('/data/app.js')
-
利用 require 方法引入 fs 核心模块
var fs = require('fs')
-
文件的读取
fs.readFile('hello.txt',function(error,data){ if(error){ console.log(data); console.log(data.toString()); }
-
文件的性质
//文件是以 二进制数据存储的 fs.readFile 读取出来的数据是16进制 //可以通过toString()方法转化我们我熟悉的汉字
-
文件的写入
// 利用fs.writeFile()方法在文件写入数据 fs.writeFile('./hello.txt',data,function(error){ if(error){ console.log('文件写入失败'); }else{ console.log("文件写入成功"); }
文件读取 FIleReader
-
javascript 内置函数
var reader = new FileReader(); reader.readASDataURL('文件'); reader.onload = function(){ console.log(reader.result); }
http 服务
- 案例
/*
* 加载http核心模块
var http =require('http');
* 创建一个Server实例
var server = http.createServer();
* 创建一个request 请求事件
*/
//加载http 核心模块
var http = require('http');
//创建一个Server 实例
var server = http.createServer();
//注册request 请求事件
//当客户端请求过来,就会自动触发服务器的request 请求事件,然后执行
//回调函数的两个参数
// request 请求对象,反映客户端的一些请求信息,例如请求路径
// response 响应对象,给客户端发送响应信息
server.on('request',function(request,response){
if(request.url=='/'){
response.write("hello,I am xiaoYi, welcome to index page");
}else if (request.url == '/login'){
response.write('hello ,welcome to login page');
}else{
response.write('sorry,is not found');
}
response.end();
})
// 绑定端口号,启动服务器
server.listen(3002,function(){
console.log("服务器启动经理撒附近成功了,可以通过http://127.0.0.1 来访问!");
})
-
字符串的两种方法
JSON.parse() 将字符串转换为数组 JSON.stringify() 数组转换为字符串
-
核心模块
Node 为JavaScript提供了很多的服务器级别的API 例如文件操作的fs核心模块,http 服务构建的http模块,os 操作系统模
-
OS 核心模块
查看cpu 信息 os.cups() 查看内存信息 os.totalmen()
nodemon
nodemon 是一个第三方模块工具,可以帮我们解决频繁修改代码重启服务器的问题
nodemon 是一个基于Node.js 开发的一个第三方命令行工具,需要独立安装
-
安装
npm install -g nodemon
-
查看版本号
nodemon --version
-
如果查看版本号错误 ,则设置 npm 的环境变量
-
查看默认路径
npm config get prefix
-
设置环境变量
C:\Users\小毅\AppData\Roaming\npm //npm 默认的路径
-
-
使用
node app.js // 使用nodemon // 只要通过nodemoe 启动的服务,它会监听你的文件变化,当文件发生变化,自动帮你重启服务 nodemon app.js
Express
-
功能,通过app.get() 方法,根据不同的请求,执行回调函数
-
安装
npm install --save express
-
起步 Express 静态服务
//安装 //引包 var express = require ('express'); //创建服务器应用程序 var app = express(); //当服务器收到get 请求时 / 的时候,执行回调函数 app.get('/',function(req,res){ res.send("hello express!"); }) app.get('/index.html',function(req,res){ res.send('你好,这就是index.html 页面'); }) //公开指定目录 app.use('/public/',express.static('./public/')) //设置监听端口 app.listen(3001,function(){ console.log('app is running at port 3001') })
-
静态服务
//直接访问public 的文件 app.use(express.static('public')) // 在要访问的文件前 + '/public/' app.use('/public',express.static('public')) //在要访问的文件前 + '/public/a/b/' app.use('/public/a/b/',express.static('/public'))
安装 配置 art- template 模板引擎
-
安装配置
npm install --save art-template npm install --save express-art-template // 同时安装 npm install --save art-template express-art-template //第一个参数用来配置视图的后缀名,这里是.art 则储存在views 目录中的模板文件必须是 .art 文件 //默认后缀是 .art app.engine('art',require('express-art-tempalate')) //修改模板文件的后缀位 .html app.engine('html',require('express-art-template'))
-
修改默认
view
视图 渲染存储目录app.set("views",目录路径)
-
使用
app.get('/',function(req,res){ //express 默认去项目中的views 目录找index.html res.render('index.html',{ title:'Hello World' }) })
路由
-
路由
-
是一种映射关系
-
请求方法
-
请求路径
- 请求处理函数
app .get('./login',函数) .get('./img/img1.jpg',函数) .get('./index.html',函数)
-
-
get
//当以GET 方法请求 / 的时候,执行对应的处理函数 app.get('/',function(req,res){ res.send('Hello World'); })
-
post:
//当以GET 方法请求 / 的时候,执行对应的处理函数 app.post('/',function(req,res){ res.send('Gpt a POST request') })
使用node操作mysql
-
安装
npm install mysql
MongoDB
-
连接数据库
//数据库连接 var mongoose = require('mongoose') mongoose.connect("mongodb://localhost:27017/study", {useNewUrlParser:true}, function(err){ if(err){ console.log('Connection Error:' + err) }else{ console.log('Connection success!') } })
-
连接数据库 插入数据
var mongoose = require('mongoose'); //连接数据库 mongoose.connect("mongodb://localhost/test", {useNewUrlParser:true}); mongoose.Promise = global.Promise; //创建一个模型 "Cat" 表名(集合) 有一个文档对象 name var Cat = mongoose.model('Cat',{name:String}); // 实例化一个 kitty 实例 var kitty = new Cat({name:'小毅'}); //持久化保存 kitty 实列 kitty.save(function(err){ if(err){ console.log(err); }else{ console.log('保存成功!'); } })
-
Schema 设计文档结构 添加约束 增加数据 查询数据 删除数据 更新数据
var mongoose = require("mongoose")
var Schema = mongoose.Schema
//链接数据库
// 指定的数据库不需要存在,当插入第一条数据之后,数据库会被创建出
// MongoClient.connect('mongodb://localhost/test',{ useNewUrlParser: true }, function(err, db) {
// });
mongoose.connect("mongodb://localhost/test", {useNewUrlParser:true}, function(err){
if(err){
console.log('Connection Error:' + err)
}else{
console.log('Connection success!') }
})
//设计文档结构 (表结构)
//约束的目的是为了保证数据的完整性,不要有脏数据
var userSchema = new Schema({
username:{
type:String,
required: true
},
password:{
type:String,
required:true
},
email:{
type:String
}
})
// 将文档结构发布为模型
// mongoose.model方法就是用来将一个架构发布为model
//第一个参数: 传入一大写名词单词字符串用来表示数据库的名称
// mongoose 自动将大写字符串生成小写复数形式的字符串
//第二个参数: 模型构造函数
// 返回值:模型构造函数
var User = mongoose.model('User',userSchema)//第一个参数是集合名,第二个参数是文档结构模型
//增加数据
// var admin = new User({
// username: "小毅",
// password: "12346",
// email: "183@qq.com"
// })
// admin.save(function(err,ret){
// if(err){
// console.log('保存失败')
// }else{
// console.log('保存成功')
// console.log(ret)
// }
// })
//查询数据
// console.log('====================查询全部===========================');
// User.find(function(err,ret){
// if(err){
// console.log('查询失败');
// }else{
// console.log(ret);
// }
// })
// console.log('====================条件查询===========================');
// User.find({
// username:'小毅'
// },function(err,res){
// if(err){
// console.log('查询失败');
// }else{
// console.log(res);
// }
// })
// console.log('====================条件查询 单个数据 返回的是对象===========================');
// User.findOne({
// //如果没有条件,那么返回的是第一个数据
// //如果有条件,但是不满足条件,则返回 null
// username:"admin"
// },function(err,rep){
// if(err){
// console.log(err)
// }else{
// console.log(rep)
// }
// })
// console.log('====================删除数据===========================');
// User.remove({
// username:'admin'
// },function(err,res){
// if(err){
// console.log('删除失败');
// }else{
// console.log('删除成功');
// }
// })
console.log('====================更新数据===========================');
//第一个参数是数据的 id 号
//第二个参数是要修改的内容
//第三个参数是回调函数
User.findByIdAndUpdate('5ebea52f357688299882fd17',{
password:'helloXiaoYi'
},function(err,rep){
if(err){
console.log('更新失败');
}else{
console.log('更新成功'+rep);
}
})
mongoose-sex-page数据分页
-
安装使用
//安装 npm install mongoose-sex-page //导入mongoose-sex-page第三方模块 const pagination = require('mongoose-sex-page') //使用 let articles = await pagination(Artical).find().page(1),size(2).display(3).populate('author').exec()
-
参数说明:
- page指定当前页
- size指定每页显示的数据条数
- display 指定客户端要显示的页码数量
- exec 向数据库中发送查询请求
-
返回的数据 articles 的内容
{ "page": 1, //当前页 "size": 2, //每页显示的条数 "total": 1, //总共的数据条数 "records": [{ //查询出来的具体数据 "cover": "\\uploads\\upload_21bbd47e2ad7af6b07155f69f497bc46.gif", "_id": "5ed9fd90245b563bf8455a98", "title": "测试", "author": { "state": 0, "_id": "5ecb59b9bb6655338ce4ae71", "username": "小毅", "email": "183@qq.com", "password""$2b$10$kri4nln1Qrbjh/nvO8i6BeHKG3JTmcILfwXpZ.49A1XeUEaEEiZoa", "role": "normal", "__v": 0 }, "publishDate": "2020-06-05T08:08:48.510Z", "content": "<p>代发发的发不发</p>", "__v": 0 }], "pages": 1, //总共页数 "display": [1] //客户端显示的页码 }
Joi
-
Joi 是对javaScritpt对象的规则描述语言和验证器
-
下载
npm install joi //引入 Joi模块 const Joi = require('joi')
-
定义对象的验证规则
const Joi = require('joi'); // alpahnum() 表示字母或数字 const schema = { username:Joi.string().min(2).max(30).required().error(new Error('用户名不通过')), password:Joi.string().regex(/^[a-zA-z0-9]{3,30}$/), access_token:[Joi.string(),Joi.number()], birthYear:Joi.number().min(1900).max(2020), email:Jon.string().emil() };
-
使用 Joi 规则验证对象
async function run(){ //实施验证 try{ await Joi.validate({username:'asf'},cheme) }catch(error){ console.log(error.message); } console.log('验证通过'); } run();
获取表单post 请求体数据 body - parser
-
安装
npm install --save body-parser
-
配置
var express = require('express') var bodyParse = require('body-parser'); var app = express() //配置 body-Parser //只要加入这个配置,则在res 请求对象就会多出来一个对象:body //也就是说可以直接通过req.body来获取post 请求数据 //par application/X-www-form-urlencode app.use(bodyParser.urlencoded({extended:false})) //parse application/json app.use(bodyParser.json())
-
使用
app.use(function(req,res){ // 配置好bade-Parser 后,那么在请求体里就会多一个 body 对象,存储的是 post请求的数据 console.log(req.body) })
-
bodyPaser 只能传递普通表单的数据,不能传递客户传递的二进制数据可以使用formidable
formidable
-
作用:
- 解析表单
- 支持get post 请求参数
- 文件上传
-
使用
//下载 formidable 模块 npm install formidable //引入formidabel 第三方模块 const formidable = require('formidable'); //引入 path 第三方模块 const path = require('path'); module.exports = (req,res) =>{ // 1、 创建表单解析对象 const form = new formidable.IncomingForm(); // 2、 配置上传文件的存放路径 form.uploadDir = path.join(__dirname,'../','../','public','uploads') // 3、 保留上传文件的后缀 form.keepExtensions = true // 4、 解析表单 form.parse(req,(err,fields,files)=>{ // 1 err 错误对像,若失败 err为错误信息 若成功 err为null // 2 fields 对象类型 保存普通表单数据 // 3 files 对象类型 保存和文件上传的相关数据 res.send(files) }) }
form 表单
-
method = " "请求方法
-
action =" " 请求地址
-
enctype =" " 指定表单数据的编码类型
-
application/x-www-form-urlcoded
name=zhansan&age=18
-
multipart/form-data
将表单数据编码成二进制类型
-
dateformat
-
dateformat 时间格式
-
使用
npm install dateformat //引入dateformat 第三方模块 返回一个方法 const dateFormat = require('dateformat') //全局配置 dateformat //导入art-template 模板引擎 const template = require("art-template") //向模板内部导入dateFormate变量 template.defaults.imports.dateFormat =dateFormat; //使用 string1要格式化的时间 string2 要格式化成什么格式 "yyyy-mm-dd" dateFormat(string1,string2)
回调函数
-
目的是获取函数中异步操作的结果,必须通过回调函数来获取
-
调用 fn() ,得到内部的data
//声明 fn function fn(callback){ setTimeout(function(){ var data = 'hello' callback(data) },1000) } //调用 fn fn(function(data){ console.log(data) })
密码加密
-
密码加密 bcrypt ,单程加密方式
//导入模块 const bcrypt = require('bcrypt'); // 随机生成字符串, gen == > generate生成盐 let salt = awit bcrypt.genSalt(10); //使用随机字符串对密码加密 let pass = await bcrypt.hash('明文密码',salt); let iavarable = bcrypt.compare("数入的密码 ","密文密码")
-
bcrypt 依赖的其他环境
1.python 2.x 2.node-gyp npm install -g node-gyp 3.windows-build-tools npm install --global --production windows-build-tools
-
安装 bcrypt
// 管理员模式下 的 powerShell npm install bcrypt
的结果,必须通过回调函数来获取
-
调用 fn() ,得到内部的data
//声明 fn function fn(callback){ setTimeout(function(){ var data = 'hello' callback(data) },1000) } //调用 fn fn(function(data){ console.log(data) })
密码加密
-
密码加密 bcrypt ,单程加密方式
//导入模块 const bcrypt = require('bcrypt'); // 随机生成字符串, gen == > generate生成盐 let salt = awit bcrypt.genSalt(10); //使用随机字符串对密码加密 let pass = await bcrypt.hash('明文密码',salt); let iavarable = bcrypt.compare("数入的密码 ","密文密码")
-
bcrypt 依赖的其他环境
1.python 2.x 2.node-gyp npm install -g node-gyp 3.windows-build-tools npm install --global --production windows-build-tools
-
安装 bcrypt
// 管理员模式下 的 powerShell npm install bcrypt