Express的基本使用

247 阅读5分钟

目录

express的基本使用

一、获取URL中携带的查询参数


		app.get('/',(req,res) =>{
        // req.query 默认是个空对象
        //客户端判断 ?name=zs&age=20 这种查询字符串,发送到服务器的参数
        // 可以通过 req.query 对象访问到
        // eg : req.query.name  req.query.age
        
		console.log(req.query)
    
    })


二、获取URL中的 动态参数

	
	app.get('/user/:id' , (req,res) =>{
		// 里面存放着通过 : 动态 匹配到的参数值
        console.log(req.params)
		         
	})

三、 express.static() 托管静态资源

        const express  = require('express')

        const  app =express()

        app.use(express.static('./clock'))


        app.listen(3000,()=>{
          console.log( '服务器已在成功启动 http://localhost:3000');
        })

挂载路径前缀


		app.use('/public',express.static('./clock') )

路由的使用

express路由使用


      const express = require('express')
     const app = express()

      app.get('/', (req,res)=>{
        res.send('hello get')
      })

      app.post('/', (req,res)=>{
        res.send('hello post')
      })


     app.listen(80, ()=>{
       console.log('http://localhost:80');
     })


模块化路由

		const express = require('express')
        const app = express()

         const router =require('./04-router.js')
         app.use(router)


        app.listen(80, ()=>{
          console.log('http://localhost:80');
        })

路由模板

      const express = require('express')
      const router = express.Router()

      router.get('/user/list', (req,res)=>{
        res.send('Get user list')
      })

      router.post('/user/add', (req,res)=>{
        res.send('Add new user')
      })

     module.exports=router

为路由模块添加前缀

		const  userRouter = require('./rouetr/user.js')
        
        app.usre('/api', userRouter)

express 中间件

全局中间件


        app.use((req,res,next)=>{
            console.log('js是世界上最好de语音');
            next()
        })

        app.get('/',(req,res)=>{
          res.send('home page')
        })

        app.get('/user',(req,res)=>{
          res.send('user page')
        })


局部中间件

        const mw =(req,res,next)=>{
           console.log('js是世界上最美丽的语音');
           next()
         }

        app.get('/',mw,(req,res)=>{
          res.send('home page')
        })

局部定义多个中间件

局部中间件 按照从前往后的 顺序执行 多个中间件

		 app.get('/',[mw1,mw2],(req,res)=>{
          res.send('home page')
        })

中间件的5个注意事项

  1. 一定要在路由之前注册中间件
  2. 客户端发送过来的请求,可以连续调用多个中间件进行处理
  3. 执行完中间件的业务代码之后,不要忘记调用next()函数
  4. 为了防止代码逻辑混乱,调用next()函数后不要再写额外的代码
  5. 连续调用多个中间件时,多个中间件之间,共享req和res 对象

中间件的分类

应用级别的中间件

通过 app.use()或app.get(),app.post() 绑定到 app 实例上的中间件 都叫应用级别的中间件

image.png

路由级别的中间件

image.png

错误级别的中间件

格式 : 错误级别中间件的function 处理函数中 ,必须有有4个形参,顺序分别是(err,req,res,next

		const express = require('express')
        const app = express()

          app.get('/',(req,res)=>{
            throw new Error('服务器内部发生了错误')
            res.send('')
          })


          app.use((err,req,res,next)=>{
            console.log('发生了错误' +err.messsage);
            res.send('Error'+err.message)
          })                      

             app.listen(3000, ()=>{
            console.log('http://localhost:3000');
          })

Express内置的中间件

  1. express.static 快速托管静态 资源的内置中间件
  2. express.json 解析JSON 格式请求体 (4.16版本)
  3. express.urlencoded 解析URL-encoded 格式的请求体数据

image.png

application/json 数据格式 {"title":"test","sub":[1,2,3]} 的方式进行编码

application/x-www-form-urlencoded 数据格式 **key1=val1&key2=val2 **

具体两者 关系前往 Express中间件

第三方中间件

  • body-parser

    • npm install body-parser
    • require 导入中间件
    • app.use()注册 使用中间件

    Express 内置的 express.urlencoded 中间件 基于 body-parser 第三方中间件 进一步封装出来的

    		const express = require('express')
            const parser = require('body-parser')
            const app = express()
              app.use(parser.urlencoded({extended:false}))      
    
              app.post('/user',(req,res)=>{
                res.send('hello my friend')
                console.log(req.body);
                })
    
                app.listen(3000, ()=>{
                console.log('http://localhost:3000');
              })
    

自定义中间件

  • ​ 手动模拟一个 express.urlencoded 解析 POST 提交到服务器表单
    • 定义中间件
    • 监听req 的data 事件
    • 使用 querystring 模块 解析请求体 数据
    • 讲解析出来的数据 对象 挂载为 res.body
    • 讲自定义中间件封装为模块

		const express = require('express')
        const app = express()
        const qs =require('querystring')        
        //调用 querystring.parse()  可将字符串转换成 对象的形式                              
		// json.stringgify()       可将JSON对象 转换成  字符串形式
        app.use((req,res,next)=>{
          let str=''
          req.on('data',(chunk)=>{		//监听data 事件 将每次传输的数据 拼接
            str += chunk

          })
          req.on('end',()=>{
           const body=qs.parse(str)			
            req.body=body
           next()
          })

        })
        app.post('/user', (req,res)=>{
          res.send(req.body)

        })

            app.listen(3000, ()=>{
            console.log('http://localhost:3000');
          })

自定义中间件的封装

		const express = require('express')
        const custombodyparser = require('./11.custombodyparser')   
        //调用封装的函数 对数据进行格式
        const app = express()                              

        app.use(custombodyparser)
        app.post('/user', (req,res)=>{
          res.send(req.body)
        })

            app.listen(3000, ()=>{
            console.log('http://localhost:3000');
          })

		const qs =require('querystring')   
         const custombodyparser= (req,res,next)=>{
          let str=''
          req.on('data',(chunk)=>{
            str += chunk

          })
          req.on('end',()=>{
           const body=qs.parse(str)
            req.body=body
           next()
          })
        }
        module.exports= custombodyparser

使用Express 写接口

  1. 创建基本的服务器

  2. 创建API路由模块

  3. 编写get 接口

  4. 编写 post 接口

        const express =require('express')
        const router =express.Router()
    
        router.get('/get',(req,res)=>{
         let query= req.query
          res.send({
            status:0,
            msg:'get请求成功',
            data:query
          })
        })
    
        router.post('/post',(req,res)=>{
          let body =req.body
          res.send({
            status:0,
            msg:'post请求成功',
            data:body
          })
        })
    
    
        module.exports= router
    

cors接口跨域问题

接口的跨域问题

  1. CORS (主流解决方案,推荐使用)
  2. JSONP (有缺陷 ,只支持GET 请求)

使用CORS 中间件 解决跨域

corsExpress 的第三方中间件 通过安装 配置 cors 中间件 解决跨域问题

  1. npm i cors
  2. const cors =require('cors')
  3. 在路由之前 调用 app.use(cors())

cors中的注意事项(1)

  1. 在路由之前 调用 app.use (cors()) // cors()
<!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>
<script src="https://cdn.staticfile.org/jquery/1.10.0/jquery.min.js"></script>
<body>
    <button id="btnGET">GET</button>
    
    <button id="btnPOST">POSt</button>
</body>
<script>
  //get 
 $('#btnGET').on('click',()=>{
  $.ajax({
    type:'GET',
    url:'http://localhost:3000/api/get',
    data:{
      name:'zt',
      age:20,
      gender:'男'
    },
    success(res){
      console.log(res);
    }   
  })
 })
 //post 

 $('#btnPOST').on('click',()=>{
  $.ajax({
    type:'POST',
    url:'http://localhost:3000/api/post',
    data:{
      bookname:'水浒传',
      autoname:'施耐庵'
    },
    success(res){
      console.log(res);
    }   
  })
 })
</script>
</html>
const express = require('express')
const app = express()
const cors = require('cors')
app.use(cors())

app.use(express.urlencoded({extended:false})) 
const apiRouter = require('./13router')
app.use('/api',apiRouter)

                                         
                                                                       
 app.listen(3000, ()=>{
   console.log('http://localhost:3000');
  })
const express =require('express')
const router =express.Router()

router.get('/get',(req,res)=>{
 const query=req.query
  res.send({
    status:0,
    msg:'get请求成功',
    data:query
  })
})

router.post('/post',(req,res)=>{
  let body =req.body
  res.send({
    status:0,
    msg:'post请求成功',
    data:body
  })
})


module.exports= router

cors中的注意事项(2)

  1. CORS 主要在服务器端进行配置,客户端无须做任何额外配置,即可请求开启CORS的接口
  2. CORS 在浏览器中有兼容性

CORS 响应头 Access-Control-Allow-Origin

​ Access-Control-Allow-Origin: |

eg: res.setHeader('Access-Control-Allow-Origin','itcast.cn') //只允许来自 itcast.cn 的请求

res.setHeader('Access-Control-Allow-Origin', ‘ * ’) //允许任何域 发起请求

回顾jSOP

概念 浏览器 通过script 标签的src 属性 请求服务器上的数据 同时 服务器返回一个函数的调用

	这种请求数据的方式 叫做JSONP

特点:

  1. JSONP 不属于AJAX 请求 因为他没有使用 XMLHTTPRequest 这个对象
  2. JSONP 仅支持 GET 请求 不支持 POST ,DELETE 等请求

创建JSONP 接口注意事项

如果项目中 已配置CORS跨域资源共享,为了防止冲突必须在配置CORS中间件之前 声明JSONP接口,否则

JSONP接口会被处理成开启CORS 的接口

		app.get('/api/jsonp',(req,res)=>{})
		app.use(cors())
		app.get('/api/get',(req,res)=>{})

在网页中使用jquery 发起jsonp 请求

调用$.ajax()函数 ,提供JSONP 的配置选择 从而发起JSONP请求

		$('#btnJSONP').on('click',()=>{
            $.ajax({
                method:'GET',
                url:'http://localhost:3000/api/jsonp',
                dataType:'jsonp',			//很关键
                success(){
                    console.log(res)
                }                                          
            })                     
        })
		app.get('/api/jsonp',(req,res)=>{
            const funcName =req.query.callback
            const data = {  name : 'zs' ,  age: 22 }
            
            const scriptStr = `${funcName}(${JSON.stringify(data)})`  //返回来调用 cb(data)
            res.send(scriptStr)
        })