node.js

node.js可以解析js代码,没有浏览器的安全级别限制。不可以使用dom、bom。

npm的使用

1
2
3
4
5
6
7
8
9
10
11
npm init 
npm install 包名 -g
npm install 包名 --save-dev
npm uninstall 包名
npm update 包名
npm info 包名 //查看包信息

#pakage文件中
"dependencies"{ "md":"^2.1.1"}} // ^代表第一个大版本不变,安装2.*.*版本
"dependencies"{ "md":"~2.1.1"}} // ~代表前两个版本不变,安装2.1.*版本
"dependencies"{ "md":"*"}} // *代表直接安装最新版本版本

开启ES模块化写法

1
2
3
4
5
6
7
8
#pakage.json文件中
{
"type""module"
}

#引用使用es6方式
import module from '.js'
export module = { }

内置模块

npm i -g nodemon 自动重启服务器

01 http模块

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//##引入http模块
let http = require('http')

// 创建服务器
http.createServer((req, res) => {
// req接受浏览器的参数,res返回渲染的内容
res.writeHead(200, { 'Content-Type': 'text/html;charset=utf-8' })
res.write(renderHTML(req.url))
res.end()
}).listen(3000, () => {
console.log('server start');
})

//##也可以
let server = http.createServer()
server.on("request",(req,res)=>{
//逻辑
})

server.listen(3000,()=>{

})

JSONP:动态创建script标签,src的指向没有跨域限制

cros请求头实现跨域

1
2
3
res.writeHead(200,{
"access-control-allow-origin":"*"
})

可以作为中间件(中间层),从接口get、pots数据,在传给前端,绕开跨域问题

02 url模块

1
2
3
4
5
6
7
//##引入url模块
let url = require('url')

url.parse( req.url,true)
//会解析出 第二个参数true可以使query 解析成为一个对象
pathname
query

03 querystring模块

1
2
3
4
5
6
7
8
9
10
11
12
13
//解析query
let querystring = require("querystring")

let str = 'name=zmxj&age=21&location=nanchang'
let obj = querystring.parse(str) // { name:'zmxj',age:'21',location:'nanchang'}

let mystr = { name:'zmxj',age:'21',location:'nanchang'}
let myobj = querystring.stringify( mystr ) //name=zmxj&age=21&location=nanchang

//数据编码
querystring.escape()
querystring.unescape()

04 events模块

1
2
3
4
5
6
7
const Event = require('events')
const event = new Event()

event.on('play', () => {
console.log('我被触发了');
})
event.emit('play')

05 fs文件操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
const fs = require('fs')
//##目录

//创建
fs.mkdir('./路径/目录名字',(err)=>{
if(err && err.code === EEXIST){
console.log('目录已经存在')
}
})

//重命名
fs.rename('./路径/目录名字','./路径/新目录',(err)=>{
if(err && err.code === ENOENT ){
console.log('目录不存在')
}
})

//删除
fs.rmdir('./路径/目录名字',(err)=>{
if(err && err.code === ENOENT ){
console.log('目录不存在')
}
})

//##文件

//创建文件
fs.writeFile('./路径/目录名字/文件名字.文件格式','内容',err=>{
//文件不存在则创建文件,文件存在则新文件会覆盖旧文件
})
//追加内容
fs.writeFile('./路径/目录名字/文件名字.文件格式','\n新内容',err=>{})

//读取内容
fs.readFile('./路径/目录名字/文件名字.文件格式','utf-8',(err,data)=>{
if(!err){
//console.log(data.toString('utf-8'))
}
})

//删除
fs.unlink('./路径/目录名字/文件名字.文件格式',err=>{})

//读取目录下文件
fs.readdir('./路径/目录名字',(err,data)=>{
if(!err){ console.log(data) }
})

存储在用户浏览器的一段不超过4kb的字符创。由name和value以及用于控制cookie有效期、安全期、适用范围的可选属性组成。

特性

  1. 自动发送
  2. 域名独立
  3. 过期时限
  4. 4kb限制

客户端第一次请求服务器时,服务器通过响应头的形式,向客户顿发送一个生份认证的cookie,客户端会自动将cookie保存在浏览器中。

随后,客户端每次请求服务器时,浏览器都会自动将cookie通过请求头的形式发送给服务器,服务器即可验证客户端身份。

cookie不具有安全性,浏览器提供了读写cookie的api,因此cookie很容易被伪装,避免存储cookie存储重要隐私数据。

express

中间件

不用修改原有代码,添加和扩展一些功能

中间件函数中可以

  1. 执行任何代码
  2. 修改request或response响应对象
  3. 结束请求响应周期
  4. 调用下一个中间件
1
2
3
4
5
6
7
8
//req 请求对象
//res 响应对象
//next 下一个中间件
//中间件的顺序很重要
app.use((req,res,next)=>{
//交出执行权,放行,往后继续匹配执行
next()
})

使用 express 托管静态文件

1
2
3
4
5
6
7
8
app.use(express.static('public'))

//可以访问 public 目录中的所有文件
http://localhost:3000/images/kitten.jpg
http://localhost:3000/css/style.css
http://localhost:3000/js/app.js
http://localhost:3000/images/bg.png
http://localhost:3000/hello.html

应用级别中间件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
let express = require('express')
const app = express()
//不限制请求路径
app.use((req,res,next)=>{
//函数体
next()
})

//限制请求路径
app.use('/home/:id',(req,res,next)=>{
//函数体
next()
})

//限制请求方法+请求路径
app.get('/home/:id',(req,res,next)=>{
//函数体
next()
})

//多个
app.get('/home/:id',
function(req,res,next){
//函数体1
next()
},function(req,res,next){
//函数体2
next()
})

//跳过其余的中间件
next('route')

//中间件还可以使用数组定义
function loa1(req,res,next){ .... next() }
function loa2(req,res,next){ .... next() }
let arr = [ loa1,loa2 ]
app.get('home/:id',arr,function(req,res,next){ ...})

路由器级别中间件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//====== 在router.js中======

const express = require('express')
//1.创建路由实例 --想低昂与一个mini express实例
const router = express.Router()

//2.路由配置
router.get('/dfg',(req,res)=>{})

//3.导出路由
module.exports = router

//====== 在app.js中======

const router = require('./router')

//4.将路由集成到express实例中 -注意执行顺序
app.use(router)

//也可以设置路径
app.use('/abc',router) // 实际请求地址为 /abc/dfg

错误处理中间件

将任何内容 传给 next() (除了字符串router) express都会将当前请求视为错误,跳过其余 中间件,进入错误处理中间件

1
2
3
4
5
6
7
8
9
10
11
//一般在所有中间件挂在完后执行错误处理中间件
//使用next(err) 进入错误处理中间件
//接收4个参数
app.use((err,req,res,next)=>{

})

//处理404
app.use((req,res,next)=>{
res.status(404).send('404 not found.')
})

内置中间件

  • json( )
  • urlencoded( )
  • raw( )
  • text( )
  • static( )

第三方中间件

搭配mysql

安装依赖

1
npm i mysql -D

在mysql中创建数据库、建表、添加数据

  • 在mysql中没有数组类型

  • 数组的值应使用JSON格式转换网站改写成JSON格式,并压缩成一行(否则会出现转移换行字符,不利于数据的使用)

  • image-20221124212209663

在node中引入并连接mysql

1
2
3
4
5
6
7
8
9
let mysql = require('mysql')
// 测试mysql
let sqlConnection = mysql.createConnection({
host: 'localhost',//主机名
user: 'root',//用户名
password: '123456',//密码
database: 'huawei_vmall'//所连接的数据库
})
sqlConnection.connect()//连接

使用mysql

  • 和调用接口一样使用

  • 使用query函数对数据库进行操作,接收参数为sql语句,回调函数第一个参数为错误,第二个参数为结果

  • 将mysql的数据使用JSON.stringify( )转换为字符串格式。

  • 在使用时使用JSON.parse( )转回来

1
2
3
4
5
6
7
8
9
10
11
12
app.get('/mysql-goodslist', function (req, res) {
let sql = "SELECT * FROM goodslist"
sqlConnection.query(sql, function (err, result) {
if (err) {
// console.log(err, '错误')
return;
}
// console.log(result, '测试结果')
res.send(JSON.stringify(result))
})
sqlConnection.end()
})

node 登录 token

安装 jsonwebtoken 用于生成和解密token

1
npm i jsonwebtoken
1
2
3
4
let jwt = require('jsonwebtoken')
// 验证成功后,生成token 返回前端
// 第一个参数是 组,第二个参数 是私钥(随便定义)
const token = jwt.sign(result[0].user_name, 'yuyu')