node下载地址:Node.js (nodejs.org)
查看node版本:
node -v
运行js文件:
node 1.js
按住shift+鼠标右键:打开Power Shell,PS是新的cmd
npm类似maven包管理工具
npm设置阿里镜像:
npm config set registry http://registry.npm.taobao.org
fs模块:
文件模块
文件的读取:
const fs = require('fs')
fs.readFile('./1.txt', 'utf8', function (err, dataStr) {
// 读取失败后的值,如果成功就是null,如果失败就是异常原因
if (err) {
return console.log('文件读取失败:' + err.message)
}
console.log(dataStr) // 读取成功后的值
})
文件的写入:
// 如果文件不存在会自动创建
fs.writeFile('./1.txt', 'BCD', 'utf8', function (err) {
if (err) {
console.log('文件写入失败:' + err.message)
}
})
// 简写
fs.writeFile('./1.txt', 'AAA', function (err) {
if (err) {
console.log('文件写入失败:' + err.message)
}
})
__dirname:当前文件所在目录
__filename:__dirname本文件全名
path模块:
路径拼接
const path = require('path')
let s=path.basename(__filename)
console.log(s) // 拿到当前文件名和路径名
s=path.basename(__filename,'.js') // 去掉扩展名
path.join('1','2','3') // 会自动加斜杆 1\2\3
s = path.extname(__filename) // 获取文件后缀名
path里面可以用../回退
@/ src目录
// 正则表达式匹配出符合条件的字符串
const regStyle = /<style>[\s\S]*<\/style>/
dataStr = regStyle.exec(dataStr)
http模块:
http模块是创建web服务器的模块
const http = require('http')
// 创建实例
const server = http.createServer()
// 事件绑定
server.on('request', (req, res) => {
res.setHeader('Content-Type', 'text/html;charset=utf-8')
const url = req.url
if ('/' === url) {
const fpath = path.join(__dirname, 'index.html')
fs.readFile(fpath, 'utf8', function (err, dataStr) {
if (err) {
return console.log('文件读取失败:' + err.message)
res.end("404")
} else {
res.end(dataStr)
}
})
} else {
res.end("404")
}
})
// 启动服务
server.listen(80, () => {
console.log('服务器启动了')
})
模块化开发:
// 内置模块:fs、path、http
const fs = require('fs')
// 自定义模块:用户自定义js文件,可以省略后缀名
// 变量不会引入
const custom=require('./custom')
// 第三方模块:例如:vue
const moment=require('moment')
module对象:
每个自定义js模块都有一个module对象,它存储了和当前模块有关的信息
模块向外共享对象:
let username = 'tom'
module.exports.username = username
module.exports.sayHello = function () {
console.log("hello")
}
// 另一种写法
module.exports = {
username: 'tom',
sayHello() {
console.log('hello')
}
}
外界引入模块共享的对象:
const index = require('./module/index')
// { username: 'tom', sayHello: [Function: sayHello] }
console.log(index)
npm包:
npm包由第三方个人或团队提供的,免费开源
查看npm的版本:
npm -v
安装第三方包:
例如:安装moment日期格式化工具
npm install moment
// 简写
npm i moment
node_moudules:
下载好了的包放在这里,存放已安装到项目中的包,require()就是从这个目录加载
package-lock.json:配置文件,记录node_moudules目录下的包的下载信息(版本等)
package.json:记录与项目有关的一些信息
安装并指定版本:
// 2 大版本 大版本升级了,后面的小版本都重置为0
// 29 功能版本
// 4 bug修复版本
npm i moment@2.29.4
多人协作:
// 打包删除node_moudules,不然太浪费了,留package.json就行了
拿到别人项目后导包到node_moudules:
npm i
-f 强制安装
运行
npm run dev
dependencies节点:
执行完导包命令后会package.json里会出现这个节点,记录用npm i命令安装了哪些包
卸载包:
npm uninstall moment
devDependencies节点:
一些包只在开发的时候用到,生产的时候不用到就放到devDependencies中,而dependencies节点是开发和生产过程都会用到
如何安装到devDependencies节点:
npm install moment --save-dev
// 简写
npm i moment -D
解决下包速度慢的问题:
换成阿里的镜像:
npm config set registry=https://registry.npmmirror.com/
Express:
基于node.js的web的http模块封装的更强大的框架,功能比node.js的http模块更强大
案例:
const express = require('express')
const app = express()
app.listen(80, () => {
console.log('服务器启动了')
})
app.get('/', function (req, res) {
// 第一种接收方式
// http://localhost?name=tom
let query = req.query
console.log(query) // { name: 'tom' }
// 第二种接收方式,适合RestFul风格
// app.get('/:id'
// http://localhost/123
let params = req.params
console.log(params) //{ id: '123' }
res.send('0')
})
托管静态资源目录:
// static目录作为静态资源文件夹托管出去
// localhost/index.html 不包含static本身
// 如果要托管多个目录,就多次编写
app.use(express.static('./static'))
// localhost/public/index.html 要加public目录才能访问到
app.use('/public',express.static('./static'))
nodemon热部署模块:
-g 是全局安装
安装:
npm i nodemon -g nodemon
启动:
nodemon index.js
模块化路由:
将路由写在模块中,然后再引入模块
模块:
const express = require('express')
const router = express.Router()
// 创建路由对象
router.get('/:uid', function (req, res) {
res.send('查询对象成功' + req.params.uid)
})
router.post('/', function (req, res) {
res.send('新建用户成功')
})
module.exports = router
主模块:
const express = require('express')
const app = express()
const user = require('./router/user')
// 统一访问前缀
app.use('/user', user)
app.listen(80, () => {
console.log('服务器启动了')
})
中间件:
app.use():注册中间件
中间件函数:类似是Spring的AOP,特点是可以在方法之前运行
全局中间件:
// 在方法前执行
const mw = function (req, res, next) {
console.log('ABC')
// 调用下一个方法
next()
}
app.use(mw)
// 简便写法
app.use((req, res, next) => {
console.log('ABC')
// 调用下一个方法
next()
})
局部中间件:
const mw1 = function (req, res, next) {
console.log('我是局部中间件函数1')
}
const mw2 = function (req, res, next) {
console.log('我是局部中间件函数2')
}
// 局部中间件生效
app.get('/', mw1,mw2, (req, res) => {
res.send('0')
})
// 局部中间件不生效
app.get('/user', (req, res) => {
res.send('0')
})
以上的是应用级别的中间件,下面是路由级别的中间件:
const express = require('express')
const app = express()
const router = express.Router()
router.use((req, res, next) => {
next()
})
app.use('/', router)
错误级别的中间件:
作用:专门用来捕获项目中的异常,防止项目崩溃,必须注册在路由之后,这样才能捕获住
例如:
app.get('/', (req, res) => {
throw new Error('服务器发生了错误')
res.send('hello')
})
app.use((err, req, res, next) => {
console.log('发生了错误:' + err.message)
res.send('err:' + err.message)
})
3个内置中间件:
express.static:静态托管中间件
app.use(express.static('./cors'))
express.json:解析json格式的请求体数据
app.use(express.json())
express.urlencoded 解析encoded格式的数据
app.use(express.urlencoded({extended:false}))
服务器通过 req.body 来获取数据
如果没有配置任何解析表单数据的中间件,则req.body的值为undefined
第三方中间件:
比如body-parser
// 安装
npm i body-parser
// 导入
const parser = require('body-parser')
// 使用
app.use(parser.urlencoded({extended: false}))
app.post('/user', (req, res) => {
let body = req.body
console.log(body)
res.send(body)
})
// express内置的express.urlencoded中间件,就是基于body-parser这个第三方中间件封装出来的
自定义中间件:
const express = require('express')
const app = express()
const qs = require('querystring')
// 自定义中间件
app.use((req, res, next) => {
let str = ''
req.on('data', (chunk) => {
str += chunk
})
// 数据接收完毕 xwfu格式
req.on('end', () => {
console.log(str)
// 用querystring模块解析数据
// [Object: null prototype] { name: 'tom', age: '18', sex: '1' }
req.body = qs.parse(str)
console.log(req.body)
})
console.log('我是自定义中间件')
next()
})
app.get('/', (req, res) => {
res.send(req.body)
})
app.listen(80, () => {
console.log('服务器启动了')
})
将自定义中间件模块化:
const qs = require('querystring')
// 自定义中间件
const bodyParser = (req, res, next) => {
let str = ''
req.on('data', (chunk) => {
str += chunk
})
// 数据接收完毕 xwfu格式
req.on('end', () => {
// console.log(str)
// 用querystring模块解析数据
// { name: 'tom', age: ' 18', sex: '1' }
req.body = qs.parse(str)
console.log(req.body)
})
console.log('我是自定义中间件')
next()
}
module.exports = bodyParser
const express = require('express')
const app = express()
const cbp = require('./module/custom-body-parser')
app.use(cbp)
app.get('/', (req, res) => {
res.send(req.body)
})
app.listen(80, () => {
console.log('服务器启动了')
})
创建本地基本服务器案例:
const express = require('express')
const apiRouter = express.Router()
apiRouter.get('/:id', (req, res) => {
let result = {
status: 0,
msg: '',
data: ''
}
result.msg = '查询用户成功:' + req.params.id
res.send(result)
})
apiRouter.post('/', (req, res) => {
const body = req.body
let result = {
status: 0,
msg: '新增用户成功',
data: ''
}
result.data = body
console.log(body)
res.send(result)
})
module.exports = apiRouter
const express = require('express')
const app = express()
const apiRouter = require('./module/apiRouter')
// 全局中间件
app.use(express.urlencoded({extended: false}))
app.use('/apiRouter', apiRouter)
app.listen(80, () => {
console.log('服务器启动了')
})
解决cors跨域问题:
协议,域名,端口有一个不同都会出现跨域问题。cors主要在服务器端配置。
npm i cors
// 解决跨域问题
const cors = require('cors')
// 在路由之前
app.use(cors())
整合MySql:
npm i mysql
// 导入
const mysql = require('mysql')
// 配置连接
const db = mysql.createPool({
host: 'localhost',
user: 'root',
password: 'root',
database: 'my_db_01'
})
// 测试
db.query('select 1', (err, result) => {
if (err) {
console.log('连接数据库失败:' + err)
} else {
console.log('连接数据库成功')
}
})
查询语句:
// 使用案例
let sqlStr = 'select * from user'
db.query(sqlStr, (err, result) => {
if (err) {
console.log('查询语句失败:' + err.message)
} else {
console.log(result)
}
})
插入语句:
// 插入语句
let sqlStr = 'insert into user(username,password,created_time) values(?,?,?)'
const user = {username: 'rose', password: 'rose', created_time: new Date()}
db.query(sqlStr, [user.username, user.password, user.created_time], (err, result) => {
if (result.affectedRows === 1) {
console.log('插入数据成功')
} else {
console.log('插入语句失败:' + err.message)
}
})
更新语句:
// 更新语句
let sqlStr = 'update user set username=?,password=? where uid=?'
const user = {uid: 9, username: '666', password: '666'}
db.query(sqlStr, [user.username, user.password, user.uid], (err, result) => {
if (result.affectedRows === 1) {
console.log('更新数据成功')
} else {
console.log('更新语句失败:' + err.message)
}
})
身份认证:
http请求是无状态的,每次请求都是独立的
session:服务器保存用户状态,客户端自动存储,自动发送
session的使用:
npm i express-session
// 导入
const session = require('express-session')
// 配置
app.use(session({
secret: 'itheima', // 任意字符
resave: false, // 固定写法
saveUninitialized: true // 固定写法
}))
案例:
// 解析解析xwfu的body
app.use(express.urlencoded({extended: false}))
app.post('/api/login', (req, res) => {
if (req.session.isLogin === true) {
return res.send({
status: 0,
msg: '登录成功'
})
} else if (req.body.username != 'root' || req.body.password != 'root') {
return res.send({
status: -1,
msg: '登录失败'
})
} else {
req.session.user = req.body
req.session.isLogin = true
return res.send({
status: 0,
msg: '登录成功'
})
}
})
清除session:
app.get('/api/logOut', (req, res) => {
// 清空session
req.session.destroy()
res.send({
status: 0,
msg: '退出登录成功'
})
})
jwt:用户保存用户状态,token里面会包含用户的信息,服务器不存数据,服务器拿到token后解密
安装:
npm i jsonwebtoken express-jwt
jsonwebtoken:生成jwt字符串
express-jwt:将jwt字符串还原成json对象
需要盐值
加密:
// 盐值
let secretKey = '123456'
// 导入加密
const jwt = require('jsonwebtoken')
// 加密部分
app.post('/api/login', (req, res) => {
// expiresIn过期时间
let tokenStr = jwt.sign({username: 'root'}, secretKey, {expiresIn: '30s'})
res.send({
status: 0,
msg: '登录成功',
token: tokenStr
})
})
解密:
// 导入解密
const {expressjwt} = require('express-jwt')
// 启用解密 unless指定哪些接口不需要访问权限
app.use(expressjwt({secret: secretKey, algorithms: ['HS256']}).unless({path: /^\/api\//}))
// 解密部分 express-jwt配置后会把用户信息挂载到req.auth
app.get('/isLogin', (req, res) => {
// 响应头:Authorization和Bearer 你的token
console.log(req.auth)
res.send({
status: 0,
msg: '登录成功',
data: {
username: req.auth.username
}
})
})
在最后放一个异常捕获,防止程序崩溃:
app.use((err, req, res, next) => {
if (err.name === 'UnauthorizedError') {
return res.send({
status: 401,
msg: '无效的token'
})
} else {
return res.send({
status: 500,
msg: '未知错误'
})
}
next()
})
ita:jwt的签发时间
exp:过期时间文章来源:https://www.toymoban.com/news/detail-499008.html
token需要前端手动去保存文章来源地址https://www.toymoban.com/news/detail-499008.html
到了这里,关于Node.js笔记的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!