nodejs-day03-中间件、路由

一、SSR服务端渲染

    1. 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>
复制代码
  • 运行结果:

返回静态页面:

image.png

image.png
返回动态页面:

image.png

    1. 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>
复制代码
  • 运行结果:

image.png

二. 传统开发模式和前端后端分离模式的区别

1. 传统开发模式

+ 前端:
   + div+css布局页面,
   + 使用js、jquery实现页面的交互,
   + 不需要发送ajax,
   + 在.jsp、.php、.asp等动态页面上写东西
+ 后端
   + 定义接口
   + 编写数据库
   + 安全维护
   + 把静态页面改成动态页面,需要发送ajax
复制代码

2. 前端后端分离模式

 + 前端
    - div + css 布局页面 

    - 使用js、jquery实现页面的交互 

    - 发送ajax请求并渲染指定的数据  

    - 使用流行的框架编写项目    
 + 后端
    - 定义接口 

    - 编写数据库 

    - 安全维护
复制代码

三、中间件

  • 中间件是一个特殊的函数,该函数有三个主要的参数:req、res、next
  • 中间件需要按照一定的先后顺序执行
  • 中间件中的req、res是共享
  • 下一个中间件想使用上一个中间件的数据,上一个中间件必须使用next
  • 中间件需要使用use调用

image.png

image.png

image.png

官方自带的
image.png

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()
  })
}
复制代码

image.png

image.png

  • log.txt:

image.png

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()
  })
}
复制代码
  • 打印的内容:

image.png

  • 发送请求:

image.png

image.png

image.png

image.png

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)
复制代码

image.png

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)
}
复制代码

image.png

image.png

五、数据库

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返回的是受影响字段

image.png

示例:

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
喜欢就支持一下吧
点赞0 分享