express

## ==2.express基础==

### 2.1 express简介

- express是基于==node==平台的,快速,开放的,极简的web开发框架
  - JavaScript ---> jQuery
  - node+http ---> express
- 官网地址:https://www.expressjs.com.cn/
- 作用:使用Express,我们可以方便、快速的创建==web网站服务器==或==API接口(纯json数据)服务器==
- 本质上:==express是一个第三方包存在于npm社区中==

### 2.2 express基础使用

#### 2.2.1 express安装

- 初始化项目、安装express

  ~~~js
  1.创建项目管家
   npm init -y
  2.下载express
   npm i express --save
  ~~~

#### 2.2.2 express基础使用

- 使用express创建web服务器

  ~~~js
  //1.引入express包
  const express = require("express");
  console.log(express); //[Function: createApplication]
  
  
  //2.创建web服务器,express:[Function: createApplication]  创建应用对象
  const app = express();
  
  
  //3.监听端口  ,回调函数,端口开放成功时调用,给开发人员看的
  app.listen(3000,()=>{
      console.log("3000端口开放成功,现在可以开始访问");
  })
  ~~~

- express响应

  ~~~js
  
  //4.响应   app.method(url,callback)
  //method:请求方法,get,post,delete,put
  //url 请求地址,必须以/开头
  //callback:回调函数,响应请求
  
  
  /*express优势: 
      1.代码更优雅,一个请求一个方法
      2.设置请求url /(根):表示首页   http://localhost:3000
      3.express响应用的是send方法
          a.返回的数据类型更灵活,根据数据类型自定义设置响应头的Content-type
          b.默认text/html;charset=utf-8,
            json : application/json; charset=utf-8
  */
  
  
  //用户发起是get请求,请求的url是/login  需要同时满足这两个条件才能触发这个请求
  app.get("/login",(req,res)=>{
                   //req:request 请求对象
                   //res:response 响应对象
      res.send({name:"web"})
  })
  
  app.get("/register",(req,res)=>{
      //req:request 请求对象
      //res:response 响应对象
  res.send("注册成功")
  })
  
  app.get("/",(req,res)=>{
      res.send("<h1>首页</h1>")
  })
  ~~~

## 3.express对象

### ==3.1 app对象==

- 使用express实例出来的对象
- 方法:app.get() / app.post() / app.delete() / app.put()

#### 3.1.1 get

- 什么是get请求

  ~~~js
  直接在浏览器地址栏直接访问地址:回车
  页面的所有src都是get请求  img / video / audio / script
  页面的所有href也是get请求  a / link 
  form请求也可以设置get请求
  ajax也可以发送get请求
  ~~~

- 作用:监听用户发起的get请求,然后去响应

- 语法:app.get(path,callback)

- 参数

  - path:必需。路径,必须/开头
  - callback:回调函数,匹配到这个请求执行的回调函数,至少有两个参数
    - req:request 对象
    - res:response对象

  ~~~js
  //4.定义请求(监听) 语法:app.get(path,callback)
  //http://localhost:3000/login?username=www&password=123
  app.get("/login",(req,res)=>{
      res.send("get发起的登录请求");
  })
  ~~~

- ==注意:get请求请求参数会直接拼接在地址栏上,以查询字符串格式传递给后台,不安全==

#### 3.1.2 post

- 什么是post请求

  ~~~js
  form请求可以设置post请求  (目前只能通过form演示post请求)
  ajax也可以发送post请求
  ~~~

- 作用:监听用户发起的post请求,然后去响应

- 语法:app.post(path,callback)

- 参数

  - path:必需。路径,必须/开头
  - callback:回调函数,匹配到这个请求执行的回调函数,至少有两个参数
    - req:request 对象
    - res:response对象

  ~~~js
  //5.定义请求(监听) 语法:app.post(path,callback)
  app.post("/login",(req,res)=>{
      res.send("post发起的登录请求");
  })
  ~~~

- ==注意:post请求参数,以请求体的方式传递到后台,相对安全==

- ==get请求和post请求的区别==

  ~~~js
  get:
      一般用于请求数据
      get参数会直接拼接在url的后面,隐蔽性差,不安全
      get参数有长度限制
      get支持缓存
  post:
      一般用于提交数据
      post参数在请求体中传递,隐蔽性较强,相对安全
      post参数没有长度限制
      post不支持缓存
  ~~~

### ==3.2 response对象==

#### 3.2.1 send

- 作用:从服务器返回数据到客户端

- ==语法:res.send(string/object)==

  - 参数
    - string:返回普通字符串,默认当作html进行渲染,text/html;charset=utf-8
    - object:返回对象,默认当作application/json形象渲染

- 基础使用

  ~~~js
  //4.定义请求 /:根  http://localhost:3000
  app.get("/",(req,res)=>{
      /* 
        语法:res.send(string/object)
          - string:返回普通字符串,默认当作html进行渲染,text/html;charset=utf-8
          - object:返回对象,默认当作application/json形象渲染
      */
     res.send("我是一个字符串:"+"<h1>首页</h1>");
  })
  
  ~~~

- ==注意:每一个请求一定会有响应,只能响应一次==

  ~~~js
  //4.定义请求 /:根  http://localhost:3000
  app.get("/",(req,res)=>{
      /* 
        语法:res.send(string/object)
          - string:返回普通字符串,默认当作html进行渲染,text/html;charset=utf-8
          - object:返回对象,默认当作application/json形象渲染
      */
     res.send("<h1>首页</h1>"+"我是一个字符串");
  
     //每一个请求一定会有响应,只能响应一次
     // Cannot set headers after they are sent to the client
     res.send({"name":"我是对象"});
  })
  ~~~

- 其他的数据类型还是需要自己设置响应头

  ~~~js
  app.get("/login",(req,res)=>{
  
      /* 
       如果返回的是字符串和对象,会默认设置响应头,但是其他的数据类型还是需要自己设置响应头
  
          原生node:res.writeHead(状态码,{"Content-type":"文件类型"})
          express:res.setHeader("Content-type","文件类型")
      */
  
      //设置响应头
      res.setHeader("Content-type","image/jpeg");
  
      //读取图片内容
      let img = fs.readFileSync(path.join(__dirname,"img/a.jpg"));
      //返回一张图片到客户端
      res.send(img);
  })
  ~~~

  ==注意:不需要刻意去记文件类型,95%以上返回的数据都是字符串或对象==

- 文件类型表:[HTTP Content-type 对照表 (oschina.net)](https://tool.oschina.net/commons)

#### 3.2.2 sendFile

- 作用:响应一个文件给客户端

- ==语法:res.sendFile(absolutefilepath)==

- 参数

  - absolutefilepath:文件路径(绝对路径)

  ~~~js
  app.get("/register", (req, res) => {
      //==语法:res.sendFile(absolutefilepath)==
      // res.sendFile("./img/a.jpg"); // path must be absolute or specify root to res.sendFile
      res.sendFile(path.join(__dirname, "img/a.jpg"))
  })
  ~~~

### 3.3 request对象

#### 3.3.1 query

- 作用:获取url地址后面的==get参数==(url?后面的查询字符串),以对象的形式返回

- ==语法:request.query==

  ~~~js
  //4.定义请求
  app.get("/login",(req,res)=>{
      //req.query:获取get的请求参数,以对象的形式
      //http://localhost:3000/login?username=123&password=456
      console.log(req.query); //{ username: '123', password: '456' }
      res.send("这个登录的响应结果");
  })
  ~~~

#### 3.3.2 params

- 动态路由:变化的路由(路径)

  ~~~js
  银河护卫队3   :   https://movie.douban.com/subject/26258779
  长空之王 (2023) : https://movie.douban.com/subject/35209731
  人生路不熟 (2023):https://movie.douban.com/subject/35653205
  这么多年 (2023):  https://movie.douban.com/subject/35591164
  灌篮高手:         https://movie.douban.com/subject/35315950
  ~~~

  电影数据庞大,操作都是一样,根据电影id的不同,返回不同的数据

  ~~~js
  //4.定义路径
  app.get("/subject/1",(req,res)=>{
      res.send("银河护卫队3")
  })
  app.get("/subject/2",(req,res)=>{
      res.send("银河护卫队3")
  })
  ....
  ~~~

- 定义动态路由:“/subject/:id”

- 作用:获取动态路径参数(动态路由)

- ==语法:request.params==

  ~~~js
  /* 
    定义动态路径
    语法:"/subject/:参数名"
    前端发请求:http://localhost:3000/subject/001
    后端接收动态路径:req.params    {id: '001' }
  */
  app.get("/subject/:id",(req,res)=>{
      //获取路径中的动态参数:req.params ,以对象的形式返回
      console.log(req.params);  // {id: '001' }
      res.send("动态路径")
  })
  ~~~

- 需求:根据前端发送的不同请求,返回不同的电影信息

  - 例:/movie/

  - 数据

    ~~~js
    let movies = [
        {id:"26258779",name:"银河护卫队3",url:"https://movie.douban.com/subject/26258779"},
        {id:"35209731",name:"长空之王 (2023)",url:"https://movie.douban.com/subject/35209731"},
        {id:"35653205",name:"人生路不熟 (2023)",url:"https://movie.douban.com/subject/35653205"},
        {id:"35315950",name:"这么多年 (2023)",url:"https://movie.douban.com/subject/35315950"}
    ]
    ~~~

  - 代码

    ~~~js
    let movies = [
        {id:"26258779",name:"银河护卫队3",url:"https://movie.douban.com/subject/26258779"},
        {id:"35209731",name:"长空之王 (2023)",url:"https://movie.douban.com/subject/35209731"},
        {id:"35653205",name:"人生路不熟 (2023)",url:"https://movie.douban.com/subject/35653205"},
        {id:"35315950",name:"这么多年 (2023)",url:"https://movie.douban.com/subject/35315950"}
    ]
    
    //4.定义请求
    app.get("/movie/:id",(req,res)=>{
    
        //5.获取动态路径参数
        let idObj = req.params; //{id:"001"}
    
        //6.查询对应id的电影信息
        let isHave = movies.find(value=>{
            return value.id == idObj.id
        });
    
        //7.返回id的电影信息
        if(isHave){
            res.send(isHave)
        }else{
            res.send("未找到该影片")
        }
    })
    ~~~

## 4.工具使用

### 4.1 nodemon

- 作用:通过nodemon运行代码,后端代码修改以后前端可以直接刷新执行,不需要重启服务器

- 下载安装(全局包,在任意位置运行以下命令即可)

  ~~~js
  npm i nodemon -g
  ~~~

- 使用:运行后台文件时把node换成nodemon执行就可以了

  ~~~js
  node 文件名
  nodemon 文件名
  ~~~

  ![image-20230509155933654](C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20230509155933654.png)

### 4.2 Rest Client

- vscode插件

- 作用:接口测试工具,测试服务器定义的路径(路由)

- 安装:在vscode中搜索插件安装

- 使用

  - 创建.http文件(在这个文件中进行测试)

  - 写测试代码

    ~~~sh
    #注释
    
    #定义变量
    @url = http://localhost:3000
    
    #书写表中的请求信息  请求方法 url
    
    #02代码中的get请求
    GET http://localhost:3000/login
    
    
    ### 两个测试请求之间用3个#隔开
    ### 02代码中的post请求
    POST http://localhost:3000/login
    
    ###
    GET {{url}}/login
    ~~~

### 4.3 代码片段

- 把常用的一些代码定义成代码片段

- 操作步骤

  - vscode中选择==文件==选项--==首选项==--==配置用户代码片段==--==新用户片段==--==输入片段名称==

  - 把==Example:==后面的代码取消注释

    ![image-20230509161156184](C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20230509161156184.png)

- 网站:https://snippet-generator.app/?description=&tabtrigger=&snippet=&mode=vscode

## 5.路由

### 5.1. 路由概述

- 什么是路由

  广义上来讲,==路由就是映射关系==。对于我们网络请求中的路由是:每一次请求对应每一个请求处理的函数。

- 现实中的路由

![3-3现实中的路由](img\3-3现实中的路由.png)

- 路由的作用

​       你想使用某种服务,那么一定有一个对应的路由。路由会给我们提供相应的服务(映射关系)

### 5.2  Express中的路由(Node的路由)

- 语法:app.method( path,callback )  

- 参数说明:

  - method:代表请求方式,比如get,post ,delete ,put
  - path:代表请求路径 ,必须以  /  开头,同时可以定义动态路径 /:参数
  - callback:代表回调函数,用户请求匹配到路由以后要做的事情。( request,response )

- ==注意:==

  - 必须包含三个方面:==请求方法、请求的路径、处理函数==  缺一不可。

  - 匹配到( 匹配成功 ):==只有方法、路径都相等才算匹配成功==

    ~~~js
    app.get("/login")
    
    post http://localhost:3000/login  匹配不成功,请求方式不一样
    get http://localhost;3000/register  匹配不成功,请求路径不一样
    
    get http://localhost;3000/login  匹配成功,请求方式和路径都一样
    ~~~

- 匹配流程

  - 每当一个请求到达服务器之后,需要先经过路由的匹配,只有匹配成功之后,才会调用对应的处理函数

    匹配成功: 一个请求方法,请求路径地址 ==(只有方法、路径都相等才算匹配成功 )==

  - 在匹配时,会按照路由的顺序进行匹配,如果请求类型和请求的 URL 同时匹配成功,则 Express 会将这次请求,转交给对应的 function 函数进行处理,主要是处理业务,并且把最终的结果响应给前端,且==一定是有结果返回==

  - 如果从上到下有相同的路由,则会匹配第1个。==定义相同的路由是没有意义的==

![](C:\Users\Administrator\Desktop\three\day07_express\note\img\3-4路由匹配流程.png)

### 5.3. express.Router 模块化路由

- 模块化:把公共的代码提出来放到一个js文件中(commonjs)

  不能把所有的路由都放到一个js文件中,不好管理和操作,要分门别类

- 不能把所有的路由信息放在一个js文件中,需要分门别类的抽离出来 。

- 使用步骤

  - 创建一个模块化路由的文件夹 routes

  - 在routes文件夹中创建模块化文件 .js

  - 编辑模块化路由代码

    ~~~js
    //1.引入express模块
    const express = require("express");
    
    //2.创建路由对象
    const routerA = express.Router();
    
    //3.定义路由(请求路径)
    routerA.get(path,callback)
    routerA.post(path,callback)
    routerA.delete(path,callback)
    routerA.put(path,callback)
    
    //4.暴露数据--只能用module.exports暴露
    module.exports = routerA
    ~~~

  - 在需要使用的js文件中引入

    ~~~js
    let rA = require("./或../模块化路由的路径");
    app.use(rA);
    ~~~

- 需求:做一个学校管理系统

  ~~~js
  学生端口:查询,添加,更新,删除
  教师端口:查询,添加,更新,删除
  管理员端口:查询,添加,更新,删除
  课程端口:查询,添加,更新,删除
  课表端口:查询,添加,更新,删除
  ~~~

  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值