后端node.js |
Node.JS
node基础
Node.js 中 JS 的组成部分
ECMAScript语法核心 + 全局成员 + 核心模块
全局成员:console、setInterval、setTimeout等
核心模块:就是 Node 平台 单独提供的一些API,这些API是Node平台所独有的
注意:Node.js 中 没有 BOM 和 DOM,取而代之的是全局成员和核心模块,只有ECMAScript是和js共有的
环境安装
检查是否安装成功
打开终端在命令行输入命令node -v即可
path环境变量配置
我的电脑 --- 右键选择属性 --- 高级系统设置 --- 高级 --- 环境变量 --- 系统变量。配置完了要重启
Nodejs 执行Js代码的方式:node ./1.js
使用REPL环境执行Js代码
- 进入 REPL 环境:打开任意终端,直接输入 `node` 并回车,就会进入到 REPL 环境中
- 离开 REPL 环境**:按两次`ctrl + c` 或者输入`.exit` 就能退出 REPL 环境
- 查看帮助:输入`.help`
核心模块
文件操作fs模块
读取文件fs.readFile方法
const fs = require('fs');
fs.readFile('./files/11.txt', 'utf-8', function (err, data) {
if (err) {
return console.log('读取文件失败:' + err.message);
}
console.log('读取文件成功,内容是' + data)
})
写入文件fs.writeFile方法
const fs = require('fs');
fs.writeFile('./files/2.txt', '6666', (err) => {
// 如果文件写入失败,则报错
if (err) {
return console.log('写入文件失败!' + err.message);
}
console.log('文件写入成功!')
}) //覆盖写入fs.writeFile方法
const fs = require('fs');
fs.appendFile('./files/3.txt', '\n333', (err) => {
if (err) {
return console.log('追加文件失败!' + err.message);
}
console.log('追加文件成功!')
}) //追加写入fs.appendFile方法
复制文件fs.copyFile方法
const fs = require('fs')
fs.copyFile('./files/1.txt', './files/1-copy.txt', (err) => {
if (err) {
return console.log('拷贝失败:' + err.message);
}
console.log('拷贝成功!')
})
获取文件信息fs.strrt方法
const fs = require('fs')
fs.stat('./files/1.txt', (err, stats) => {
if (err) {
return console.log(err.message)
}else{
console.log(stats.size) // 单位是 字节
console.log(stats.birthtime)
console.log(stats.isFile()) // 判断是否为文件
console.log(stats.isDirectory()) //判断是否为目录
}
})
读取指定目录中所有文件的名称 fs.readdir方法
const fs = require('fs');
fs.readdir('./', function (err, files) {
console.log(files);
});
路径操作
获取当前文件的所在目录:console.log(_dirname);
获取当前文件的绝对路径:console.log(_filename);s
path模块
拼接路径path.join方法
const path = require('path');
// 返回: '/foo/bar/baz/asdf'等同于'/foo/bar/baz/asdf/quux/..'
// .. 表示上一级目录,会被抵消
path.join('/foo', 'bar', 'baz/asdf', 'quux', '..');
路径分割符path.sep属性
const path = require('path');
console.log(path.sep);
获取路径的最后一部分之前的所有路径path.dirname(path)
const path = require('path');
// 返回 /a/b
console.log(path.dirname('/a/b/c'));
模块和包
核心模块:由 node 本身提供,不需要单独安装,可以直接使用,如:fs模块
自定义模块:由我们自己创建的模块
// First.js
// 这里面定义的所有变量,只在该模块内生效,其它模块是无法使用的
var name = '二狗子';
var user = {
name: name,
age: 18
};
console.log(user.name);
console.log(module);
module对象
id:当前模块id
exports:表示当前模块暴露给外部的值
parent:表示调用当前模块的模块(谁加载的模块)
children:表示当前模块调用的模块(当前模块加载了哪些模块)
filename:模块的绝对路径
paths:模块的搜索路径,从当前模块开始查找node_modules目录,然后依次进入到父目录,查找父目录下的node_modules目录;依次迭代,直到根目录下的node_modules目录
loaded:一个布尔值,表示当前模块是否被完全加载
模块间数据共享(实现代码的复用)
// Second.js
// 下面这两种都是合法的
var F = require('./First');
var F = require('./First.js');
console.log(F);
借助global对象
// First.js
var name = '二狗子';
// 将我们的变量绑定到全局对象上去
global.name = name;
// Second.js
var F = require('./First.js');
// 我们使用global全局对象可以访问到其它模块绑定的值了
console.log(global.name);
// 依然是个空对象
console.log(F);
使用module.exports与exports暴露数据
exports 和 module.exports的区别
1. module.exports默认引用了一个空对象
2. 对外暴露数据是,永远以 module.exports为准
3. exports是 module.exports的一个引用
4. 对exports直接赋值,会切断与 module.exports 之间的联系,也就是说下面的操作是不能正确暴露数据的
// First.js
var name = '二狗子';
let age = 18;
// module.exports 默认是一个空对象
console.log(module.exports);
// 将想暴露的数据暴露出来
module.exports.name = name;
module.exports.xxx = age;
// Second.js
var F = require('./First.js');
// 打印的是:{ name: '二狗子', xxx: 18 }
// 我们可以看到,在First.js中暴露的数据可以在这里接收到
console.log(F);
包(package)
包的规范
1.每个包都要以一个单独的文件夹存在
2.每个包都要有一个package.json文件,而且必须在包的最顶层目录
3.package.json文件采用的是json语法
4.package.json的内容必须包含name(包的名称),version(包的版本),main(包的入口文件)属性
引入包:和模块点导入一样,都是用require导入
require('包的路径');
// 根据包的路径导入
require('./mypackage1');
require('../mypackage2');
第三方模块:别人编写的模块,我们可以使用npm安装后使用
包管理工具npm的使用
全局包:
全局包是指安装到计算机全局环境中的包;可以在当前电脑的任何目录下,直接通过命令行来访问
安装全局包:
# 命令格式
npm install -g 包名称
# 或者
npm i -g 包名称
卸载全局包:
# 命令格式
npm uninstall -g 包名称
本地包
本地包就是指针对项目的包,会被安装到项目根目录下的node_modules目录下
安装本地包:
# 命令格式
npm install 包名称
# 或者
npm i 包名称
# 或者 (对于低版本的npm工具,需要加上--save)
npm install 包名称 --save
# 如果使用cnpm安装,一定要加上--save
# 如果不加--save,该包不会被加入到项目的package.json这个里面的dependencies项里面
cnpm install 包名称 --save
安装开发阶段包:
# 命令格式
npm install 包名称 --save-dev //开发阶段安装方法
# 或者
npm install 包名称 -D
例:npm install webpack -D
根据package.json文件包的安装
npm install
# 或者
npm i
上线项目包的安装
npm install --production
# 或者
npm i --production
卸载本地包:
# 命令格式
npm uninstall 包名称
发布一个自己的npm包
1.初始化:初始化一个包的配置信息:package.json
npm init
2.编写包的功能(略)
3.发布:去npm的https://www.npmjs.com/官网注册一个账号,然后在命令行切换当前包的根目录,使用下面的命令登录:npm login 根据提示,输入username、password、email
登录成功后就可以使用命令发布:npm pubish
4.取消发布:# 撤销最新的发布
npm unpublish
# 指定版本撤销发布(注意本地的package.json文件中的版本号设置要和要撤销的一致)
npm unpublish 包名@版本号
核心http模块的简单使用
https://i.csdn.net/#/uc/profile(可前往查看)
supervisor和modemon的使用
supervisor:是工具型的模块,建议安装全局包
安装命令:npm install -g supervisor
# 如果有安装过cnpm的话,可以使用下面的方式安装
cnpm install -g supervisor
安装完毕怎么启动:node ./server.js(老方法)
新方法:supervisor ./server.js
nodemon安装:
npm install -g nodemon
# 如果有安装过cnpm的话,可以使用下面的方式安装
cnpm install -g nodemon
安装完毕怎么启动:nodemon ./server.js
后端mongodb
Linux操作系统下安装mongodb
操作系统:CentOS6,要求:64位
使用二进制安装:阿里云镜像:mongodb-server: https://mirrors.aliyun.com/mongodb/yum/redhat/6/mongodb-org/4.0/x86_64/RPMS/mongodb-org-server-4.0.6-1.el6.x86_64.rpm
使用rpm包安装(推荐):
步骤一: wget https://mirrors.aliyun.com/mongodb/yum/redhat/6/mongodb-org/4.0/x86_64/RPMS/mongodb-org-server-4.0.6-1.el6.x86_64.rpm
wget https://mirrors.aliyun.com/mongodb/yum/redhat/6/mongodb-org/4.0/x86_64/RPMS/mongodb-org-shell-4.0.6-1.el6.x86_64.rpm
步骤二:rpm -ivh mongodb-org-server-4.0.6-1.el6.x86_64.rpm
rpm -ivh mongodb-org-shell-4.0.6-1.el6.x86_64.rpm
启动和连接:
首先:建数据存放目录和日志存放目录和日志文件
# 创建数据存放目录
mkdir /usr/local/mongodb/data/
# 创建日志存放目录和日志文件
mkdir /usr/local/mongodb/logs/
touch /usr/local/mongodb/logs/mongodb.log
启动服务端
# 启动
service mongod start
# 重启
service mongod restart
# 关闭
service mongod stop
# 设置开机启动
chkconfig mongod on
启动客户端
# 启动客户端连接服务端
mongo
# 连接远程的服务端
mongo 192.168.1.100:27017
#客户端的更多使用方式查看
mongo --help
基本的使用:
库和表的基本使用
# 查看数据库
show dbs
show databases
# 查看数据表(其实叫集合更合适)的列表
show tables
show collections
# 切换数据库
use tableName
# 查看命令帮助
db.help()
# 删除tableName表,tableName为表名称
db.tableName.drop()
# 删除当前切换到的数据库
db.dropDatabase()
# 创建表
db.createCollection(tableName)
数据的基本操作
1.插入数据
# 基本语法
db.tableName.insert()
例:db.user.insertMany([{'name':'郭昌松','age':20}, {'name':'李志友','girl':['李文斌','李志光']}])
2.查询数据:
# 基本语法
db.tableName.find(where, fileds)
例:db.user.find({name:'baba'})
以格式化后的结构展示查询结果:db.tableName.find(where).pretty()
3.删除数据:
# 基本语法 db.member.remove(where,justOne) ,高版本的MongoDB支持新的API:`deleteOne()` 和 `deleteMany()`
例:db.remove.find({name:'user'})
4.更新数据:
# 基本语法
db.tableName.update(where, data, upsert, multi)
db.user.update({name: 'baba'},{'money': 99999999998})
更多条件规则:
逻辑运算符的使用:db.member.find({name: 'baba', age: 30})
范围运算符 $in、$nin:db.member.find({age: {$in: [20, 22, 24]}})
自定义查询 $where:db.member.find({ $where: function(){
# this 指当前记录, 即每一条记录。查询会扫描整个表中的所有数据
return this.age > 20;
}
})
排序 sort():# age按照降序 sex按照升序
db.member.find().sort({age: -1, sex: 1})
统计 count():db.member.find().count()
db.member.find({条件}).count()
去重 distinct() :# 去重字段要被引号包着
express框架的使用
也可参看我的博客express:https://blog.csdn.net/bigpatten
初识
安装:npm install express --save
响应文件内容 `response.sendFile()`
使用该方法可以发送文件的内容,不过该方法只能接受绝对路径(如果只有一个参数的话),有两个参数的时候可以使用相对路径。
自定义模板引擎:art-template
安装:npm install art-template express-art-template --save
配置使用`art-template`作为模板引擎
// 导入express模块
const express = require('express');
// 基于express创建服务器
const app = express();
// 自定义模板引擎的信息
// 参数1:给模板引擎起的名字(和模板文件的后缀名有关)
app.engine('html', require('express-art-template'));
// 配置使用的模板引擎
app.set('view engine', 'html');
// 配置模板文件的存放路径
app.set('views', __dirname + '/views');
// 这是设置路由
app.get('/', function(req, res){
// 使用模板引擎渲染模板
// res.render('xxx', {name: '二狗子'});
res.render('111.html', {name: '二狗子'})
});
//启动,监听80端口
app.listen(80, '127.0.0.1', function () {
console.log('启动成功');
});
路由模块
应用级别的路由:
// 导入express模块
const express = require('express');
// 基于express创建服务器
const app = express();
// 这是设置路由规则
// 对应的地址是:http://127.0.0.1/
app.get('/', function(req, res){
res.send('首页');
});
// 对应的地址是:http://127.0.0.1/user
app.get('/user', function(req, res) {
res.send('用户中心');
});
app.listen(80, '127.0.0.1', function () {
console.log('启动成功');
});
路由模块的使用
1. 封装路由模块
// router.js
// 创建路由对象
const express = require('express')
const router = express.Router()
// 设置路由规则
// 对应的地址是:http://127.0.0.1/
router.get('/', (req, res)=>{
res.send('首页');
})
// 对应的地址是:http://127.0.0.1/user
router.get('/user', (req, res)=>{
res.send('用户中心');
})
// 导出路由对象
module.exports = router
2. 注册路由模块
// 导入express模块
const express = require('express');
// 导入自定义路由模块
const router = require('./router');
// 基于express创建服务器
const app = express();
// 注册路由模块
app.use(router);
app.listen(80, '127.0.0.1', function () {
console.log('启动成功');
});
中间件
基本概念
简单来说,中间件就是一段程序的开头到结尾的中间部分的众多逻辑处理工序
在experss中中间件一般表现为一个函数,这个函数包括3个参数:
1. request请求对象
2. response响应对象
3. next(),表示调用下一个中间件
express 框架中对中间件的5种分类
应用级别的中间件
使用app.use()或者app.METHOD() 绑定到app对象上的中间件。app.METHOD()指的是:app.get()、app.post()等方法。比如:`app.get('URL地址', (req, res, next)=> {})
路由级别的中间件
路由级别的中间件和应用级别的中间件其实是一样的,只是它绑定到express.Router()实例对象中, 比如: router.get('url地址', (req, res, next)=>{})
错误级别的中间件
错误级别的中间件的回调函数中,有四个参数 app.use((err, req, res, next)=>{}),一个都不能少,如果少了会被当成常规中间件处理,将无法处理错误。
内置的中间件
在express 4.x中,只有一个内置中间件: express.static(),用来处理静态资源的。不过从express 4.16.0开始,又新增了两个:
1. express.json 使用JSON负载解析传入的请求
2. express.urlencoded 使用URL编码的有效内容解析传入的请求
第三方中间件
非express框架提供的,一般是第三方个人或者组织编写的,需要程序员手动安装才能使用的中间件
使用express.static中间件处理静态资源
假如我们的项目images目录下有一个1.jpg,那么该资源对应的url就是:http://127.0.0.1/1.jpg
写法一:
// 导入express模块
const express = require('express');
// 基于express创建服务器
const app = express();
// app.use表示注册中间件
// images目录下的静态文件会自动帮我们根据名字处理
app.use(express.static('./images'));
app.listen(80, '127.0.0.1', function () {
console.log('启动成功');
});
写法二:
// 导入express模块
const express = require('express');
// 基于express创建服务器
const app = express();
// app.use第一个参数可以指定一个虚拟路径,记住要有/开头
app.use('/xxx', express.static('./images'));
app.listen(80, '127.0.0.1', function () {
console.log('启动成功');
});
按照写法二,那么1.jpg对应的url就是:http://127.0.0.1/xxxx/1.jpg,这样,从url上来看,文件好像存放到一个叫xxxx的目录中一样。
使用中间件获取请求数据
GET请求数据获取(无需使用中间件)
get请求和post请求的区别:get接收参数使用req.query,post接收参数使用req.body
获取使用get请求传来的数据
const express = require('express');
const app = express();
// 获取get请求传来的数据
app.get('/x1', function (req, res) {
console.log(req.query);
});
app.listen(80, '127.0.0.1', function () {
console.log('启动成功');
});
获取使用post请求传来的数据
// 导入express模块
const express = require('express');
// 基于express创建服务器
const app = express();
// 处理静态文件
app.use(express.static('./html'));
// 这里仅做演示之用,没有考虑数据的分块上传处理
app.use(function (req, res, next) {
req.on('data', function (data) {
// 将我们拿到的数据,注册到req对象上
req.body = data.toString();
// 调用next函数,交给下一个中间件处理
next();
})
})
// 获取post请求传来的数据
app.post('/x2', function (req, res) {
// 直接在req.query上是获取不到的
// console.log(req.query);
// 我们可以在前面使用app.use自己写个中间件获取
console.log(req.body);
});
app.listen(80, '127.0.0.1', function () {
console.log('启动成功');
});
使用第三方中间件body-parser
安装:cnpm install body-parser --save
使用:
// 导入express模块
const express = require('express');
// 引入包
const bodyParser = require('body-parser');
// 基于express创建服务器
const app = express();
// 处理静态文件
app.use(express.static('./html'));
// 注册中间件
// 注册后,req对象中会多个body属性来存放传来的数据
app.use(bodyParser.urlencoded({extended: false}));
// 获取post请求传来的数据
app.post('/x2', function (req, res) {
console.log(req.body);
});
app.listen(80, '127.0.0.1', function () {
console.log('启动成功');
});
路由的规则
传统路由
使用 app.get() 或者 app.post()`指定完整的url匹配
app.get ('/xxx', function (req, res) {
console.log('我好帅');
console.log(req.query);
})
参数路由
app.get('/xxx', function (req, res) {
console.log('我好帅');
console.log(req.query);
})
cookie和session
参看我的博客:https://blog.csdn.net/bigpatten
部署
开启Gzip压缩
安装:npm install compression
在服务端启用中间件
// 启用传输压缩中间件
const compression = require('compression');
app.use(compression());
使用pm2模块管理进程
pm2是一个Node应用的进程管理器,使用它可以方便的管理我们的node进程。
安装:npm install -g pm2
使用方法说明:
# 启动进程,如果不起别名,默认使用服务器文件名,这里用的是e1
# 相同名字的进程只能启动一个
pm2 start ./e1.js
# 启动进程并起个别 名叫ss
pm2 start ./e1.js --name ss
# 启动4个进程
pm2 start ./e1.js -i 4
# 根据有效CPU数目启动最大进程数目
pm2 start ./e1.js -i max
# 显示所有进程状态
pm2 list
# 监视所有进程的状态 q退出
pm2 monit
# 显示所有进程日志 ctrl+c退出
pm2 logs
# 根据id查看日志
pm2 logs 0
# 根据name查看日志
pm2 logs e1
# 停止所有进程
pm2 stop all
# 启动所有进程
pm2 start all
# 重启所有进程
pm2 restart all
# 平滑的重载所有进程
pm2 reload all
# 删除所有进程
pm2 delete all
# 根据进程id启动进程
pm2 start 0
# 根据进程id停止进程
pm2 stop 0
# 根据进程id重启进程
pm2 restart 0
# 根据进程id重载进程
pm2 reload 0
# 根据进程id删除一个进程
pm2 delete 0
# 根据进程name启动进程
pm2 start ss
# 根据进程name停止进程
pm2 stop ss
# 根据进程name重启进程
pm2 restart ss
# 根据进程name重载进程
pm2 reload ss
# 根据进程name删除一个进程
pm2 delete ss
序列化ROM
sequelize的使用
模型的使用
增加数据:模型 . create()
简单举个例子:
// 引入模型
const cl = require('./models.cl');
// 添加数据
cl.create(data)
.then((result) => {
console.log(result);
})
.catch(function(err){
console.log(err);
});
删除数据:模型 . destory()
简单举个例子:
// 引入模型
const cl = require('./models.cl');
// 删除操作
cl.destroy({
// 条件设定
where: {id: id}
}).then(data => {
console.log(data)
})
修改数据
模型. update()
模型. save()
查询数据
模型. findOne()
模型. find. All()
模型. findorCreate()
模型. findAndCountAll()