一、SSR服务端渲染
-
- art-template
- 安装并引入art-template
yarn add art-template 复制代码
-
把模板和数据整合成字符串
-
使用 res.end 响应
(1)引入express
const express=require('express')
const path=require('path')
const artTemplate=require('art-template')
复制代码
(2)创建服务
const app=express()
复制代码
(3)监听客户端请求
app.get('/index.html',(req,res)=>{
// res.send('express server')
// 返回静态页面
//res.sendFile(path.join(__dirname, './views/index.html'))
//模拟后端数据
var obj={
name:'fly',
age:18,
hobby:['干饭','睡觉','看小说']
}
//把页面和数据结合返回一个字符串
var html=artTemplate(path.join(__dirname,'./views/index.html'),obj)
res.end(html)
})
复制代码
(4)监听端口
app.listen(3000,()=>{
console.log('http:127.0.0.1:3000')
})
复制代码
- index.html页面:
<body>
<h1>art-template </h1>
<!-- 标准语法 -->
{{name}}
{{age}}
{{each hobby}}
{{$index}} {{$value}}
{{/each}}
<!-- 原始语法 -->
<%=name%>
<%=age%>
<%for(var i = 0; i<hobby.length;i++){%>
<%=hobby[i]%>
<%}%>
</body>
复制代码
- 运行结果:
返回静态页面:
返回动态页面:
-
- ejs
- 安装ejs
- 设置模板引擎和模板位置(固定的,不能改)
app.set('view engine','ejs') app.set('views',模板所在的文件夹) 复制代码
- 使用render渲染页面
res.render('index.ejs',obj) 复制代码
(1)引入express
const express = require('express') const path = require('path') 复制代码
(2)创建服务
const app = express() //可以通过带有/views前缀地址来访问views目录下的文件了 app.use('/views', express.static(path.join(__dirname, './views'))) 复制代码
(3)设置模板引擎和模板位置
// 设置使用哪个模板引擎 app.set('view engine', 'ejs') // 设置模板的位置 app.set('views', path.join(__dirname, './views')) 复制代码
(4)监听客户端请求
app.get('/index.html', (req, res) => { // 模拟后端数据 var obj = { name: 'fly', age: 18, hobby: ['干饭', '睡觉', '上钟'] } //使用render渲染页面 res.render('index.ejs', obj) }) 复制代码
(5)监听端口
app.listen(3000, () => {
console.log('http://127.0.0.1:3000')
})
复制代码
- index.ejs页面(不支持标准语法,只能使用原始语法)
<body>
<h1>ejs </h1>
<!-- 原始语法 -->
<%=name%>
<%=age%>
<%for(var i=0; i<hobby.length;i++){%>
<%=hobby[i]%>
<%}%>
</body>
复制代码
- 运行结果:
二. 传统开发模式和前端后端分离模式的区别
1. 传统开发模式
+ 前端:
+ div+css布局页面,
+ 使用js、jquery实现页面的交互,
+ 不需要发送ajax,
+ 在.jsp、.php、.asp等动态页面上写东西
+ 后端
+ 定义接口
+ 编写数据库
+ 安全维护
+ 把静态页面改成动态页面,需要发送ajax
复制代码
2. 前端后端分离模式
+ 前端
- div + css 布局页面
- 使用js、jquery实现页面的交互
- 发送ajax请求并渲染指定的数据
- 使用流行的框架编写项目
+ 后端
- 定义接口
- 编写数据库
- 安全维护
复制代码
三、中间件
- 中间件是一个特殊的函数,该函数有三个主要的参数:req、res、next
- 中间件需要按照一定的先后顺序执行
- 中间件中的req、res是共享
- 下一个中间件想使用上一个中间件的数据,上一个中间件必须使用next
- 中间件需要使用use调用
官方自带的
1.中间件的基本使用
// 1. 引入express
const express = require('express')
const path = require('path')
// 2. 创建服务
const app = express()
app.use(middleWare)
app.use((req, res, next) => {
req.body.name = 'fly'
next()
})
// 3. 监听客户端请求
app.get('/', (req, res) => {
console.log(req.body)
res.send('express server')
})
// 4. 监听端口
app.listen(3000, () => {
console.log('http://127.0.0.1:3000')
})
function middleWare(req, res, next) {
req.body = {
}
next()
}
复制代码
2.日志中间件
// 1. 引入express
const express = require('express')
const path = require('path')
const fs = require('fs')
const app = express()
app.use(middleWateLog)
// 3. 监听客户端请求
app.get('/sd', (req, res) => {
res.send(req.title)
})
app.get('/fy', (req, res) => {
res.send(req.title)
})
// 4. 监听端口
app.listen(3000, () => {
console.log('http://127.0.0.1:3000')
})
function middleWateLog(req, res, next) {
let data1 = ''
if (req.url === '/sd') {
data1 = '欢迎来到对抗路'
} else if (req.url === '/fy') {
data1 = '不要来捉我'
}
let data = `请求的路径为:${req.url}---请求的方式为:${req.method}---${data1}\n`
fs.appendFile(path.join(__dirname, './log.txt'), data, 'utf8', err => {
req.title = data1
next()
})
}
复制代码
- log.txt:
3.表单解析中间件
// 1. 引入express
const express = require('express')
const app = express()
const middleWateLog = require('./middleware/middleWareLog')
const bodyParser = require('./middleware/bodyParser')
app.use(middleWateLog)
app.use(bodyParser)
// 3. 监听客户端请求
app.get('/sd', (req, res) => {
res.send(req.title)
})
app.get('/fy', (req, res) => {
res.send(req.title)
})
app.post('/api/post', (req, res) => {
console.log(req.body)
res.send('post')
})
app.post('/api/about', (req, res) => {
console.log(req.body)
res.send('about')
})
// 4. 监听端口
app.listen(3000, () => {
console.log('http://127.0.0.1:3000')
})
复制代码
- bodyParser.js:
const querystring = require('querystring')
module.exports = (req, res, next) => {
let str = ''
// 监听传递的参数
req.on('data', chunk => {
str += chunk
})
// 监听数据传递完毕,进一步处理
req.on('end', () => {
req.body = querystring.parse(str.toString())
next()
})
}
复制代码
- middleWareLog.js
const path = require('path')
const fs = require('fs')
module.exports = (req, res, next) => {
let data1 = ''
if (req.url === '/sd') {
data1 = '欢迎来到对抗路'
} else if (req.url === '/fy') {
data1 = '不要来捉我'
}
let data = `请求的路径为:${req.url}---请求的方式为:${req.method}---${data1}\n`
fs.appendFile(path.join(__dirname, '../log.txt'), data, 'utf8', err => {
req.title = data1
next()
})
}
复制代码
- 打印的内容:
- 发送请求:
4.第三方表单解析中间件
// 1. 引入express
const express = require('express')
const app = express()
const middleWateLog = require('./middleware/middleWareLog')
// const bodyParser = require('./middleware/bodyParser')
app.use(middleWateLog)
// app.use(bodyParser)
// 使用第三方表单解析中间件
// const bodyParser = require('body-parser')
// app.use(bodyParser.urlencoded({ extended: false }))
// app.use(bodyParser.json())
// 使用express内部自带的表单解析中间件
app.use(express.urlencoded({ extended: false }))
app.use(express.json())
// 3. 监听客户端请求
app.get('/sd', (req, res) => {
res.send(req.title)
})
app.get('/fy', (req, res) => {
res.send(req.title)
})
app.post('/api/post', (req, res) => {
console.log(req.body)
res.send('post')
})
app.post('/api/about', (req, res) => {
console.log(req.body)
res.send('about')
})
// 4. 监听端口
app.listen(3000, () => {
console.log('http://127.0.0.1:3000')
})
复制代码
四、路由
4.1 路由
路由是一种对应关系
- 前端路由
- 后端路由
前端请求的url地址和后端对该地址的处理函数的对应关系
4.11.路由的基本使用
- 引入路由的两种方式:
//方式1
// const router = require('./routes/index.js')
// app.use(router)
//方式2
// 引进来的:require('./routes/index.js')是一个函数,所以要有括号以及参数,以及router那边的函数也要有形参
require('./routes/index.js')(app, express)
复制代码
4.2 路由传参的三种方式
- get
- query
//http://127.0.0.1:3000/fly?name=fly&age=18 router.get('/fly',(req,res)=>{ console.log(req.query.name) console.log(req.query.age) res.send('发育') }) 复制代码
- params
//http://127.0.0.1:3000/fly/fly/18
router.get('/fly/:name/:age',(req,res)=>{
console.log(req.params.name)
console.log(req.params.age)
res.send('发育')
})
复制代码
- post
//body-parser
app.use(bodyParser.urlencoded({entended:false}))
app.use(bodyParser.json())
//官方自带的
app.use(express.urlencoded({extended:false}))
app.use(express.json())
复制代码
-
解析 body 不是 nodejs 默认提供的,你需要载入 body-parser 中间件才可以使用 req.body
-
路由的基本使用.js:
const express = require('express')
const app = express()
// const middleWateLog = require('./middleware/middleWareLog')
// app.use(middleWateLog)
app.use(express.urlencoded({ extended: false }))
app.use(express.json())
//方式1
// const router = require('./routes/index.js')
// app.use(router)
//方式2
// 引进来的:require('./routes/index.js')是一个函数,所以要有括号以及参数
require('./routes/index-back.js')(app, express)
app.listen(3000, () => {
console.log('http://127.0.0.1:3000')
})
复制代码
- index-back.js:
module.exports = (app, express) => {
const router = express.Router()
router.get('/sd', (req, res) => {
res.send(req.title)
})
// http://127.0.0.1:3000?name=fly&age=18
router.get('/fy', (req, res) => {
console.log(req.query.name)
console.log(req.query.age)
res.send('发育')
})
// http://127.0.0.1:3000/fly/18
router.get('/fy/:name/:age', (req, res) => {
console.log(req.params.name)
console.log(req.params.age)
res.send('发育')
})
router.post('/api/post', (req, res) => {
console.log(req.body)
res.send('post')
})
router.post('/api/about', (req, res) => {
console.log(req.body)
res.send('about')
})
app.use(router)
}
复制代码
五、数据库
5.1环境安装
phpstudy wamp mamp
5.2可视化工具
navicat
六、在nodejs中操作数据库
1.下载包
yarn add mysql
复制代码
2.引入mysql模块
const mysql=require('mysql')
复制代码
3.创建连接
const connection = mysql.createConnection({
host: '127.0.0.1',
user: 'root',
password: 'root',
database: 'my_db_2101'
})
复制代码
4.开启连接
connection.connect(err => {
if (err) return console.log(err.message)
console.log('开启成功')
})
复制代码
5.实现具体操作
// sql 语句
// params 参数(可以是数组)
// callback 回调
const sql = 'select * from user where isdel = 0'
connection.query(sql, (err, results) => {
if (err) return console.log(err.message)
console.log(results)
})
复制代码
- 如果是查询操作,result返回的是具体的信息
- 如果是添加、更新、删除等操作,result返回的是受影响字段
示例:
1.入口文件:
const express = require('express')
const app = express()
app.use(express.urlencoded({ extended: false }))
//extended: false:表示使用系统模块querystring来处理,也是官方推荐的
app.use(express.json())
require('./routes/index2.js')(app, express)
app.listen(3000, () => {
console.log('http://127.0.0.1:3000')
})
复制代码
2.路由
module.exports = (app, express) => {
const mysql = require('mysql')
const connection = mysql.createConnection({
host: '127.0.0.1',
user: 'root',
password: 'root',
database: '2101_3'
})
connection.connect(err => {
if (err) return console.log(err.message)
console.log('成功开启')
})
const router = express.Router()
//请求资源
router.get('/users', (req, res) => {
const sql = 'select * from user where label=0'
connection.query(sql, (err, result) => {
if (err) return res.send({ status: 1, message: '请求失败' })
res.send({
status: 0,
message: result
})
})
})
//根据id请求资源
router.get('/users/:id', (req, res) => {
const sql = 'select * from user where label=0 and id=?'
connection.query(sql, req.params.id, (err, result) => {
if (err) return res.send({ status: 1, message: '请求失败' })
if (result.length === 0) return res.send({ status: 1, message: '不存在' })
res.send({
status: 0,
message: result
})
})
})
//增加
router.post('/addUser', (req, res) => {
const sql = 'insert into user set ?'
connection.query(sql, req.body, (err, result) => {
if (err) return res.send({ status: 1, message: '请求失败' })
if (result.affectedRows !== 1) return res.send({ status: 1, message: '添加失败' })
res.send({
status: 0,
message: 'success'
})
})
})
//根据id修改
router.post('/updateUser/:id', (req, res) => {
const sql = 'update user set ? where id=?'
connection.query(sql, [req.body, req.params.id], (err, result) => {
if (err) return res.send({ status: 1, message: '请求失败' })
if (result.affectedRows !== 1) return res.send({ status: 1, message: '更新失败' })
res.send({
status: 0,
message: 'success'
})
})
})
//根据id删除
router.get('/deleteUser/:id', (req, res) => {
const sql = 'update user set label=1 where id=?'
connection.query(sql, req.params.id, (err, result) => {
if (err) return res.send({ status: 1, message: '请求失败' })
if (result.affectedRows !== 1) return res.send({ status: 1, message: '删除失败' })
res.send({
status: 0,
message: 'success'
})
})
})
app.use(router)
}
复制代码
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END