express框架学习

express是node框架

它把所有后端需要做的事情给你准备好

把大部分的行为都封装成了方法(服务)

预留了一个接口位置,可以把很多插件直接注册进去

使用

1使用npm install express 下载

2导入使用 const express = require('express')

3创建服务

=>导入进来后就是一个函数,执行就会返回一个服务

=>express()

=>返回值是一个服务

监听端口  listen(8000,()=>{})

4依靠express创建服务去监听端口

express 返回响应

express框架把所有请求分类

按照请求方式分类

get,post,delete,patch,put....

分别使用服务去调用

这些方法的参数是一致的

xxx('路径',callback)每个请求处理函数里面 接收一个req,res

req表示本次请求的信息 res本次响应的信息

res里面多了一个方法叫做send() 还保留了end方法

end方法只能返回字符串类型

send方法当你返回一个其他数据类型的时候,会给你自动转换成json格式返回

后端路由

路由:根据前端的不同请求给出不同的响应

我们在处理业务逻辑的时候就可以把所有请求分类放好

express最初实现路由就是app.get() app.post()...

const express =require('express')

const app =express()

//对每个请求的分别处理就叫做后端路由
app.get('/a',(req,res)=>{
  res.send({name:'Jack',age:18})
})
app.post('/a',(req,res)=>{
  res.send('我接收了post请求的/a路径标识符')
})
app.delete('/a',(req,res)=>{
  res.send('我是来自delete请求')
})
app.listen(3000,()=>console.log('在3000端口运行'))

express路由表

express框架单独给有api,不进行路由处理,只是单独配置一张表,把配置好的表交给服务,让服务按照这个表的配置进行路由

express对象有个成员叫做Router,是一个函数当这个函数执行的时候会返回一个路由表(一个空的表格)可以在这个表格上进行各种路由的配置

得到空表格后,向表格上添加内容

get(),post(),delete(),...

语法:xxx(路径标识符,回调函数)

告诉app服务,要使用的表格

方法: app.use('要使用的东西')

这样就可以按照模块化开发的方式,把路由表配置单独拿出去了

把请求分类

按照业务逻辑分类

  =>  用户相关

  => 商品相关

。。。。

//任务:创建出一个表就可以
const express = require('express')

//建立表
const router = express.Router()

//向表里添加内容

router.get('/getInfo',(req,res)=>{
  res.send('我是get请求 /getInfo 路径标识符')
})
router.post('/login',(req,res)=>{
  res.send('我是get请求 /login 路径标识符')
})
router.post('/reg',(req,res)=>{
  res.send('我是get请求 /reg 路径标识符')
})
//导出表格
module.exports =router

挂载路由表出现的问题

        app.use是有执行顺序的

        当你挂载多张表以后,就会出现后面的路由去前面的表里面空跑

        当你挂载多个路由表以后,最好使用app.use进行分类

                不属于你的路由不要进来 

        可以进行约定

        用户相关的路由,标识符以/users开头

        商品相关的路由,标识符以/goods开头

app.use()

=>第一个参数选填,默认是“*”,可以写一个字符串表示以这个字符串开头的标识符,使用后面挂载的内容

=>第二个参数,就是挂载内容

const express =require('express')
//把准备好的路由表导入进来
const userRouter =require('./route/user')
const goodRouter =require('./route/goods')
const app =express()
//告诉app使用哪个表
//只有以/users开头的请求,会使用这个表
app.use('/user',userRouter)
app.use('/goods',goodRouter)
app.listen(3000,()=>console.log('在3000端口运行'))

静态资源配置

前端的静态资源

        =>前端使用js css images videos ...第三方

        =>静态资源最好是统一以/public开头,express给我们提供了一个静态资源的方法

          要求都以统一的/public开头

          剩下的就以public以后的目录书写

express.static(‘静态资源存储路径’)  

        在所有路由表挂载的最前面挂载以下静态资源的处理

        配置静态资源的时候,最好配置两个

        1.自己写的静态资源

        2.第三方静态资源

const express = require('express')
const viewsRouter = require('./route/views')
const app =express()
//挂载静态资源
//所有的/public开头都会去到public文件夹下寻找内容
//按照你请求路径后面的内容去寻找
app.use('/public',express.static('./public'))
app.use('/node_modules',express.static("../node_modules"))
app.use('/views',viewsRouter)

app.listen(3000,()=>console.log('在3000端口运行'))

接收参数的处理

express对于地址后面携带的参数做了单独处理

get形式的参数

在req里面添加了一个叫做quert的成员,在里面就是解析好的请求参数

express并没有处理body,但有个接口

插件叫做body-parser专门解析请求体的插件,但不能解析文件

express内置了这个插件

使用

1.使用express内置,在挂载在服务上,在进入路由之前,把请求解析好

挂载express.urlencoded()

挂载以后,会在req里面添加新成员body

里面就是所有请求的请求体信息

2.使用body-parser插件

const express = require('express')
const testRouter =require('./route/test')
const app =express()
app.use(express.urlencoded())



app.use(testRouter)
app.listen(3000,()=>console.log('在3000端口运行'))



//测试路由表
const router = require('express').Router()

router
  .get('/a',(req,res)=>{
    //准备接收参数
    const {url,query} =req
    console.log(url);
    console.log(query);
    res.send({
      message:'接收参数成功!',
      param:query
    })
  })
  .post('/a',(req,res)=>{
    console.log(req.body);
    res.send({
      message:'接收post参数请求成功!',
      body:req.body
    })
  })
  module.exports =router

文件上传

在前端把本地img 视频 音频之类的文件发给服务端,服务端存储在服务器里面,把文件地址存储到数据库里面

前端把文件传递给后端

直接form表单上传

原生JS上传

JQuery上传文件

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <!-- 表单直接上传
  form标签设置
  action设置服务器地址
  method Post方式
  enctype application/mutilpart
  enctype请求头里面的content-type
  mutilpart设置以二进制流的形式上传
  input 
    type选择file
    name设置名字
  -->
  <form action="http://localhost:3000/upload" method="post" enctype="multipart/form-data">
    <input type="file" name="pic">
    <input type="text" name="username">
    <button>上传</button>
  </form>
</body>

</html>
<!-- 原生js上传 -->
<!-- <script>
  /* 原生js上传需要HTTP/2.0的技术提供了内置构造函数叫做FormData()
     语法:new FormData(form元素)
     返回一个包含form元素里面所有带name属性元素的值
  */
  // 1.获取元素绑定事件
  const form =document.querySelector('form')
  form.addEventListener('submit',function(e){
    e.preventDefault()
    //2.拿到文件
    const formData =new FormData(this)
    //3.正常ajax发送
    const xhr =new XMLHttpRequest()
    xhr.open('POST','地址')
    //不需要单独设置请求头
    //因为formData会自动设置请求头
    xhr.send(formData)

    xhr.onload=()=>{

    }
  })
</script> -->
<!-- jquery上传文件 -->
<script src="../../node_modules/jquery/dist/jquery.min.js"></script>
<script>
  /*
    jquery上传和原生js基本一致
    绑定事件
    使用FormData()拿到数据
    使用$.ajax()

    问题formData会自动设置请求头,jquery也会
    jquery会默认设置成application/x-www-form-urlencoded
    formData会发送二进制流的形式
    jquery会把所有的数据给你直接格式化成key=value&key=value
  */
  $('form').submit((e) => {
    e.preventDefault()
    const formData = new FormData($('form')[0])

    $ajax({
      method: "POST",
      url: 'http://localhost:3000/upload',
      data: formData,
      contentType: false,//不要动请求头,直接上传
      processData: false,//不要管数据,直接上传
      success(res) {
        console.log(res);
      }
    })

  })
</script>

后端接收文件后存储起来

        单文件上传

        单名称多文件上传、

        多名称多文件上传

//单文件上传简单的
/*1.跨域问题
  下载一个包cors npm install cors
  2.接收文件
  准备文件夹,在服务器上存储上传的文件
  需要一个插件帮助
  multer
  下载 npm install multer
  配置
  导入
  需要使用multer配置一个接收器
  multer({dest:'存放文件的路径'})
  使用接收器去接收文件
  哪一个路由需要接收文件,就配置在哪个路由上
  写在路由标识符的后面,路由处理函数的前面
  接收器.single('前端上传的文件的key)
  在路由处理函数里面
  会在req上多一个信息file,这就是上传文件的信息
  注意:会把你的文件存储起来,但是没有后缀,随机命名
*/
// const express = require('express')
// const router =express.Router()
// //导入cors插件
// const cors = require('cors')
// //导入multer插件
// const multer = require('multer')
// //使用multer去生成一个接收器
// //配置的接收,将接收到文件存储在指定目录
// const fileUpload = multer({dest:'./uploads/'})
// const app = express()
// //挂载上cors就跨域了
// app.use(cors())
// //在需要的路由上进行配置
// router.post('/upload',fileUpload.single('pic'),(req,res)=>{
//   console.log('接收请求');
//   console.log(req.file);
// })
// app.use(router)
// app.listen(3000,()=>console.log('端口3000'))


//单文件上传复杂版本
/* 
  先生成一个仓库信息
  multer.diskDtirage({配置})
    =》 destitnation:function(){} 设定存储路径
    =》 filename:function(){} 设定文件名称
  返回值:是一个仓库信息
  使用multer生成一个接收器
  接收器里面配置一个仓库信息
  语法:multer({storage:仓库信息})
  */ 
const express = require('express')
const path = require('path')
const router =express.Router()
//导入cors插件
const cors = require('cors')
//导入multer插件
const multer = require('multer')
//使用multer生成一个仓库信息
const storage =multer.diskStorage({
  destination:function(req,file,cb){
    //req,本次请求信息
    //file,本次请求路径
    //cb,回调函数,利用回调函数来设定存储路径
    //第一个参数null,表示不要修改二进制文件
    cb(null,'./uploads/')
  },
  filename:function(req,file,cb){
    //req,本次请求信息
    //file,本次上传文件信息
    //cb,回调函数,通过回调函数来设定文件名称
    console.log(file);
    //从file信息里把后缀名取出,拼接随机数
    const tmp =path.extname(file.originalname)
    cb(null,`pic_${new Date().getTime()}-${Math.random().toString().slice(2)}${tmp}`)
  }   
})
// 配置接收器,带有仓库信息
const fileUpload = multer({storage})
const app = express()
//挂载上cors就跨域了
app.use(cors())
//在需要的路由上进行配置
router.post('/uploads',fileUpload.single('pic'),(req,res)=>{
  console.log('接收请求');
  console.log(req.file);
})
app.use(router)
app.listen(3000,()=>console.log('端口3000'))

// single方法是专门接收单文件的,一个名称配一个文件
// array方法是专门接收多文件的,一个名称配多个文件  //单名称多文件
// field方法是专门接收多文件,多个名称配多文件  //多名称多文件
//在后面的路由处理函数里面就不能接收req.file
//file是单文件
//files是多文件(以一个数组的形式,里面存储着每个文件信息)
//单名称多文件
// const express = require('express')
// const router =express.Router()
// //导入cors插件
// const cors = require('cors')
// //导入multer插件
// const multer = require('multer')
// //使用multer去生成一个接收器
// //配置的接收,将接收到文件存储在指定目录
// const fileUpload = multer({dest:'./uploads/'})
// const app = express()
// //挂载上cors就跨域了
// app.use(cors())
// //在需要的路由上进行配置
// router.post('/upload',fileUpload.array('pic'),(req,res)=>{
//   console.log('接收请求');
//   console.log(req.files);
// })
// app.use(router)
// app.listen(3000,()=>console.log('端口3000'))
//多名称多文件
const express = require('express')
const path = require('path')
const router =express.Router()
//导入cors插件
const cors = require('cors')
//导入multer插件
const multer = require('multer')
//使用multer生成一个仓库信息
const storage =multer.diskStorage({
  destination:function(req,file,cb){
    //req,本次请求信息
    //file,本次请求路径
    //cb,回调函数,利用回调函数来设定存储路径
    //第一个参数null,表示不要修改二进制文件
    cb(null,'./uploads/'+file.fieldname)
  },
  filename:function(req,file,cb){
    //req,本次请求信息
    //file,本次上传文件信息
    //cb,回调函数,通过回调函数来设定文件名称
    console.log(file);
    //从file信息里把后缀名取出,拼接随机数
    const tmp =path.extname(file.originalname)
    cb(null,`${file.fieldname}_${new Date().getTime()}-${Math.random().toString().slice(2)}${tmp}`)
  }   
})
// 配置接收器,带有仓库信息
const fileUpload = multer({storage})
const app = express()
//挂载上cors就跨域了
app.use(cors())
//在需要的路由上进行配置
router.post('/upload',fileUpload.fields([
  {name:'pic'},
  {name:'photo'}
]),(req,res)=>{
  console.log('接收请求');
  console.log(req.files);
})
app.use(router)
app.listen(3000,()=>console.log('端口3000'))
上一篇:使用工厂模式+反射技术创建对象


下一篇:vue+nodejs实现文件上传