zoukankan      html  css  js  c++  java
  • Express 框架简介

    1、Express 框架简介及初体验

    1.1、Express 框架是什么

    Express 是一个属于 Node 平台的 Web 应用开发框架,它提供了一系列的强大特性,帮助你创建各种 Web 应用

    我们可以使用 npm install express 命令进行下载安装。

    1.2、Express 框架特性

    ●提供了方便简洁的路由定义方式

    ●对获取 HTTP 请求参数进行了简化处理

    ●对模板引擎支持程序高,方便渲染动态 HTML 页面

    ●提供了中间件机制,有效控制 HTTP 请求

    ●拥有大量第三方中间件对功能进行扩展

    1.3、原生 Node.js 与 Express 框架对比之路由 

    原始 node.js 代码:

    app.on('request', (req, res) => {
      // 获取客户端的请求路径
      let { pathname } = url.parse(req.url);
      // 对请求路径进行判断 不同的路径地址响应不同的内容
      if (pathname == '/' || pathname == '/index') {
        res.end('欢迎来到首页');
      } else if (pathname == '/list') {
        res.end('欢迎来到列表页');
      } else if (pathname == '/about') {
        res.end('欢迎来到关于我们页');
      } else {
        res.end('抱歉,您访问的页面出错了');
      }
    });

    express 框架代码:

    // 当客户端以 get 方式访问 / 时
    app.get('/', (req, res) => {
      // 对客户端做出响应
      res.send('Hello Express');
    });
    // 当客户端以 post 方式访问 /add 路由时
    app.get('/add', (req, res) => {
      // 对客户端做出响应
      res.send('使用 post 方式请求了 /add 路由');
    });

    例子:

    新建 framework 项目文件夹,并切换到命令行工具,输入:npm install express 下载安装框架。

    新建 01.js 文件:

    // 引入 express 框架
    const express = require('express');
    // 创建网站服务器
    const app = express();
    
    app.get('/', (req, res) => {
      // send() 向客户端响应
      // 1、send() 内部会检测响应内容的类型
      // 2、send() 会自动设置 http 状态码
      // 3、send() 会帮我们自动设置响应的内容类型及编码
      res.send('hello express');
    })
    
    // 监听端口
    app.listen(3000);
    console.log('网站服务器启动成功');

    切换到命令行工具,输入:

    node 01.js

    打开浏览器,输入:http://localhost:3000/ 可以看到:

    在增加一个 /list:

    // 引入 express 框架
    const express = require('express');
    // 创建网站服务器
    const app = express();
    
    app.get('/', (req, res) => {
      // 1、send() 内部会检测响应内容的类型
      // 2、send() 会自动设置 http 状态码
      // 3、send() 会帮我们自动设置响应的内容类型及编码
      res.send('hello express');
    })
    
    app.get('/list', (req, res) => {
      res.send({name: '张三', age: 20});
    })
    
    // 监听端口
    app.listen(3000);
    console.log('网站服务器启动成功');

    重新运行:node 01.js

    刷新页面可以看到:

    2、中间件

    2.1、什么是中间件

    中间件就是一堆方法,可以接收客户端发来的请求,可以对请求做出响应,也可以将请求继续交给下一个中间件继续处理。

    中间件方法由 Express 提供,负责拦截请求,请求处理函数由开发人员提供,负责处理请求。

    app.get('请求路径', '处理函数') // 接收并处理get请求
    app.post('请求路径', '处理函数') // 接收并处理post请求

    可以针对同一个请求设置多个中间件,对同一个请求进行多次处理。

    app.get('/request', (req, res, next) => {
      req.name = '张三';
    next() }) app.get(
    '/request', (req, res) => { res.send(req.name); })

    可以调用 next 方法将请求的控制权交给下一个中间件,直到遇到结束请求的中间件。

    例子:新建 02.js 文件:

    // 引入 express 框架
    const express = require('express');
    // 创建网站服务器
    const app = express();
    
    app.get('/request', (req, res, next) => {
      req.name = '张三';
      next();
    });
    
    app.get('/request', (req, res) => {
      res.send(req.name);
    });
    
    // 监听端口
    app.listen(3000);
    console.log('网站服务器启动成功');

    在命令行工具中输入:nodemon 02.js

    回到浏览器输入:http://localhost:3000/request ,可以看到:

    2.2、app.use 中间件用法 

    app.use 匹配所有的请求方式,可以直接传入请求处理函数,代表接收所有的请求。

    app.use((req, res, next) => {
      console.log(req.url);
      next();
    });

    app.use 第一个参数也可以传入请求地址,代表不论什么请求方式,只要是这个请求地址就接收这个秦秋。

    app.use('/admn', (req, res, next) => {
      console.log(req.url);
      next();
    });

    例子:新建 03.js 文件:

    // 引入 express 框架
    const express = require('express');
    // 创建网站服务器
    const app = express();
    
    // 接收所有请求的中间件
    app.use((req, res, next) => {
      console.log('请求走了 app.use 中间件')
      next()
    })
    // 当客户端访问 /request 请求的时候,才走当前的中间件
    app.use('/request', (req, res, next) => {
      console.log('请求走了 app.use /request 中间件')
      next()
    })
    
    app.get('/list', (req, res) => {
      res.send('/list');
    })
    
    app.get('/request', (req, res, next) => {
      req.name = '张三';
      next();
    });
    
    app.get('/request', (req, res) => {
      res.send(req.name);
    });
    
    // 监听端口
    app.listen(3000);
    console.log('网站服务器启动成功');

    在命令行工具输入:nodemon 03.js

    在浏览器中输入:http://localhost:3000/request

    在浏览器中输入:http://localhost:3000/list

    2.3、中间件应用

    1、路由保护,客户端在访问需要登录的页面时,可以先使用中间件判断用户登录状态,用户如果未登录,则拦截请求,直接响应,禁止用户进入需要登录的页面。

    例子:新建 04.js 文件:

    // 引入 express 框架
    const express = require('express');
    // 创建网站服务器
    const app = express();
    
    app.use('/admin', (req, res, next) => {
      // 用户没有登录
      let isLogin = false;
      // 如果用户登录
      if (isLogin) {
        // 让请求继续向下执行
        next()
      } else {
        // 如果用户没有登录,直接第客户端做出响应
        res.send('您还没有登录,不能访问当前页面');
      }
    })
    
    app.get('/admin', (req, res) => {
      res.send('您已经登录,可以访问当前页面');
    })
    
    // 监听端口
    app.listen(3000);
    console.log('网站服务器启动成功');

    在命令行工具中输人:nodemon 04.js

    在浏览器中输入:http://localhost:3000/admin ,可以看到:

    把 isLogin 改为: let isLogin = true;,在重新刷新页面,可以看到:

    2、网站维护公告,在所有路由的最上面定义接收所有请求的中间件,直接为客户端做出响应,网站正在维护中。

    例子:继续编辑 04.js 文件:

    // 引入 express 框架
    const express = require('express');
    // 创建网站服务器
    const app = express();
    
    // 网站维护公告
    app.use((req, res, next) => {
      res.send('当前网站正在维护中...');
    })
    
    app.use('/admin', (req, res, next) => {
      // 用户没有登录
      let isLogin = true;
      // 如果用户登录
      if (isLogin) {
        // 让请求继续向下执行
        next()
      } else {
        // 如果用户没有登录,直接第客户端做出响应
        res.send('您还没有登录,不能访问当前页面');
      }
    })
    
    app.get('/admin', (req, res) => {
      res.send('您已经登录,可以访问当前页面');
    })
    
    // 监听端口
    app.listen(3000);
    console.log('网站服务器启动成功');

    回到浏览器中,随便输入那个请求地址,页面都显示:

    3、自定义 404 页面

    中间是有顺序的,如果从上到下都没有匹配成功,那么就说明用户访问的这个请求路径是不存在的。

    例子:继续编辑 04.js 文件:

    // 引入 express 框架
    const express = require('express');
    // 创建网站服务器
    const app = express();
    
    // 网站维护公告
    // app.use((req, res, next) => {
    //   res.send('当前网站正在维护中...');
    // })
    
    app.use('/admin', (req, res, next) => {
      // 用户没有登录
      let isLogin = true;
      // 如果用户登录
      if (isLogin) {
        // 让请求继续向下执行
        next()
      } else {
        // 如果用户没有登录,直接第客户端做出响应
        res.send('您还没有登录,不能访问当前页面');
      }
    })
    
    app.get('/admin', (req, res) => {
      res.send('您已经登录,可以访问当前页面');
    })
    
    app.use((req, res, next) => {
      res.send('当前访问的页面不存在');
    })
    
    // 监听端口
    app.listen(3000);
    console.log('网站服务器启动成功');

    在浏览器中输入:http://localhost:3000/add 可以看到:

    不过在 network 里看到的状态码是 304

    要想显示为 404 的话,需要修改代码:

    app.use((req, res, next) => {
      // 为客户端响应 404 状态码以及提示信息
      // res.status(404)
      res.status(404).send('当前访问的页面不存在');
    })

    刷新页面后可以看到:

    2.4、错误处理中间件

    在程序执行的过程中,不可避免的会出现一些无法预料的错误。比如文件读取失败,数据库连接失败等。

    错误处理中间件是一个集中处理错误的地方。

    代码示例:

    app.use((err, req, res, next) => {
      res.status(500).send('服务器发生未知错误');
    })

    例子:新建 05.js 文件:

    // 引入 express 框架
    const express = require('express');
    // 创建网站服务器
    const app = express();
    
    app.get('/index', (req, res) => {
      throw new Error('程序发生了未知错误')
    })
    
    // 错误处理中间件
    app.use((err, req, res, next) => {
      res.status(500).send(err.message);
    })
    
    // 监听端口
    app.listen(3000);
    console.log('网站服务器启动成功');

    在命令行工具中输入:nodemon 05.js

    在浏览器中输入:http://localhost:3000/index ,可以看到:

    注意:错误处理中间件只能捕捉到同步代码执行出错。如果异步代码执行出错,需要手动去触发这个错误中间件。

    当程序出现错误时,调用 next() 方法,并且将错误信息通过参数的形式传递给 next() 方法,即可触发错误处理中间件。

    示例代码:

    app.get('/', (req, res, next) => {
      fs.readFile('./file-dose-exist', (err, data) => {
        if (err) {
          next(err);
        }
      })
    })

    例子:修改 05.js 文件:

    // 引入 express 框架
    const express = require('express');
    // 创建网站服务器
    const app = express();
    const fs = require('fs');
    
    app.get('/index', (req, res, next) => {
      // throw new Error('程序发生了未知错误')
      // res.send('程序正常执行')
      fs.readFile('./demo.txt', 'utf8' ,(err, result) => {
        if (err != null) {
          next(err)
        } else {
          res.end(result)
        }
      })
    })
    
    // 错误处理中间件
    app.use((err, req, res, next) => {
      res.status(500).send(err.message);
    })
    
    // 监听端口
    app.listen(3000);
    console.log('网站服务器启动成功');

    在浏览器中刷新页面,可以看到:没有找到文件

    如果修改为当前目录下有的文件:

    fs.readFile('./01.js', 'utf8' ,(err, result) => {

    刷新浏览器,可以看到:

    2.5、捕获错误

    在 node.js 中,异步 API 的错误信息都是通过回调函数获取的,支持 Promise 对象的异步 API 发生错误可以通过 catch() 方法捕获。

    异步函数执行如果发生错误要如何捕获错误呢?

    try catch 可以捕获异步函数以及其他同步代码在执行过程中发生的错误,但是不能捕获其他类型的 API 发生的错误。

    语法:

    app.get('/', (req, res, netx) => {
      try {
        await User.find({name: '张三'});
      } catch (ex) {
        next(ex);
      }
    });

    例子:新建 06.js 文件:

    // 引入 express 框架
    const express = require('express');
    // 创建网站服务器
    const app = express();
    const fs = require('fs');
    const promisify = require('util').promisify;
    const readFile = promisify(fs.readFile);
    
    app.get('/index', async (req, res, next) => {
      try {
        await readFile('./aaa.js')
      } catch (ex) {
        next(ex);
      }
    })
    
    // 错误处理中间件
    app.use((err, req, res, next) => {
      res.status(500).send(err.message);
    })
    
    // 监听端口
    app.listen(3000);
    console.log('网站服务器启动成功');

    刷新浏览器,可以看到:

    3、Express 请求处理

    3.1、构建模块化路由

    基础代码:

    const express = require('express');
    // 创建路由对象
    const home = express.Router();
    // 将路由和请求路径进行匹配
    app.use('/home', home);
    // 在 home 路由下继续创建路由
    home.get('/index', (req, res) => {
      // /home/index
      res.send('欢迎来到博客展示页面');
    });

    例子:新建 07.js 文件:

    // 引入 express 框架
    const express = require('express');
    // 创建网站服务器
    const app = express();
    
    // 创建路由对象
    const home = express.Router();
    // 为路由对象匹配请求路径
    app.use('/home', home);
    // 创建二级路由
    home.get('/index', (req, res) => {
      res.send('欢迎来到博客展示页面');
    })
    
    // 监听端口
    app.listen(3000);
    console.log('网站服务器启动成功');

    在命令行工具中输入:nodemon 07.js

    在浏览器中输入:http://localhost:3000/home/index ,可以看到:

    构建模块化路由代码:

    // home
    const home = express.Router();
    home.get('/index', () => {
      res.send('欢迎来到博客展示页面');
    });
    module.exports = home;
    
    // admin
    const admin = express.Router();
    admin.get('/index', () => {
      res.send('欢迎来到博客管理页面');
    });
    module.exports = admin;
    
    // app.js
    const home = require('./route/home.js');
    const admin = require('./route/admin.js');
    app.use('/home', home);
    app.use('/admin', admin);

    例子:在项目根目录下新建 route文件夹,并新建 home.js 和 admin.js 文件:

    // home.js
    const express = require('express');
    const home = express.Router();
    home.get('/index', (req, res) => {
      res.send('欢迎来到博客展示首页');
    });
    module.exports = home;
    
    // admin.js
    const express = require('express');
    const admin = express.Router();
    admin.get('/index', (req, res) => {
      res.send('欢迎来到博客管理首页');
    });
    module.exports = admin;

    新建 08.js 文件:

    // 引入 express 框架
    const express = require('express');
    // 创建网站服务器
    const app = express();
    const home
    = require('./route/home'); const admin = require('./route/admin'); // 为路由对象匹配请求路径 app.use('/home', home); app.use('/admin', admin); // 监听端口 app.listen(3000); console.log('网站服务器启动成功');

    在命令行工具中输入:nodemon 08.js

    打开浏览器输入:http://localhost:3000/home/index  和 http://localhost:3000/admin/index ,可以看到:

    3.2、GET参数的获取

    Express框架中使用 req.query 即可获取 GET 参数,框架内部会将 GET 参数转换为对象并返回。

    示例代码:

    // 接收地址栏中问号后面的参数
    // 例如: http://localhost:3000/?name=zhangsan&age=30
    app.get('/', (req, res) => {
        console.log(req.query); // {"name": "zhangsan", "age": "30"}
    });

    例子:新建 09.js 文件:

    // 引入 express 框架
    const express = require('express');
    // 创建网站服务器
    const app = express();
    
    app.get('/index', (req, res) => {
      // 获取 get 请求参数
      res.send(req.query);
    })
    
    // 监听端口
    app.listen(3000);
    console.log('网站服务器启动成功');

    在命令行工具中输入:nodemon 09.js

    在浏览器中输入:http://localhost:3000/index?name=zhangsan&age=30 ,可以看到:

    3.3、POST 参数的获取

    Express 中接收 post 请求参数需要借助第三方包 body-parser

    下载安装:npm install body-parser

    示例代码:

    // 引入 body-parser 模块
    const bodyParser = require('body-parser');
    // 配置 body-parser 模块
    app.use(bodyParser.urlencoded({ extended: false }));
    // 接收请求
    app.post('/add', (req, res) => {
      // 接收请求参数
      console.log(req.body);
    });

    例子:

    在命令行工具输入:npm install body-parser

    新建 10.js 文件:

    // 引入 express 框架
    const express = require('express');
    // 引入 body-parser 模块
    const bodyParser = require('body-parser');
    // 创建网站服务器
    const app = express();
    
    // 拦截所有的请求
    // extended: false 方法内部使用 querystring 模块处理请求参数的格式
    // extended: true 方法内部使用第三方模块 qs 处理请求参数的格式
    app.use(bodyParser.urlencoded({ extended: false }))
    
    app.post('/add', (req, res) =>{
      // 接收 post 请求参数
      res.send(req.body)
    })
    
    // 监听端口
    app.listen(3000);
    console.log('网站服务器启动成功');

    在命令行工具中输入:nodemon 10.js

    我们通过表单的形式来发送 post 请求,新建 post.html 文件:

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title>Document</title>
    </head>
    <body>
      <form method="POST" action="http://localhost:3000/add">
        <input name="username" type="text">
        <input name="password" type="password">
        <button type="submit">sbmit</button>
      </form>
    </body>
    </html>

    右键点击在浏览器中打开,然后随便输入一些信息,点击提交,可以看到:

    例子:新建 11.js 文件:

    // 引入 express 框架
    const express = require('express');
    // 引入 body-parser 模块
    const bodyParser = require('body-parser');
    // 创建网站服务器
    const app = express();
    
    app.use(fn ())
    
    function fn() {
      return function (req, res, next) {
        console.log(req.method)
        next()
      }
    }
    
    app.get('/', (req, res) => {
      res.send('ok');
    })
    
    // 监听端口
    app.listen(3000);
    console.log('网站服务器启动成功');

    在命令行工具中输入:nodemon 11.js

    在浏览器中输入:http://localhost:3000/ ,可以看到:

     

    这就证明了返回的函数 fn 被调用了。

    这样做的好处是:我们在调用 fn 函数的同时,向 fn 函数内部传递一些额外的参数;在请求处理函数内部,可以根据这个参数改变请求处理函数的行为。

    修改 11.js 文件代码:

    // 引入 express 框架
    const express = require('express');
    // 引入 body-parser 模块
    const bodyParser = require('body-parser');
    // 创建网站服务器
    const app = express();
    
    app.use(fn ({a: 1}))
    
    function fn(obj) {
      return function (req, res, next) {
        if ( obj.a == 1) {
          console.log(req.url)
        } else {
          console.log(req.method)
        }
        next()
      }
    }
    
    app.get('/', (req, res) => {
      res.send('ok');
    })
    
    // 监听端口
    app.listen(3000);
    console.log('网站服务器启动成功');

    刷新浏览器,可以看到命令行工具中的:请求地址

    如果把 app.use(fn ({a: 1})) 改为 app.use(fn ({a: 2}))

    刷新浏览器,可以看到:请求方法

    3.4、Express 路由参数

    示例代码:

    app.get('/find/:id', (req, res) => { 
         console.log(req.params); // {id: 123} 
    });
    // 浏览器中打开 localhost:3000/find/123

    例子:新建 12.js 文件:

    // 引入 express 框架
    const express = require('express');
    // 引入 body-parser 模块
    const bodyParser = require('body-parser');
    // 创建网站服务器
    const app = express();
    
    app.get('/index/:id', (req, res) => {
      res.send(req.params)
    })
    
    // 监听端口
    app.listen(3000);
    console.log('网站服务器启动成功');

    在命令行工具中输入:nodemon 12.js

    在浏览器中输入:http://localhost:3000/index/123 ,可以看到:

    如果是多个参数的话:

    app.get('/index/:id/:name/:age', (req, res) => {
      res.send(req.params)
    })

    在浏览器中输入:http://localhost:3000/index/123/zhangsan/20

    3.5、静态资源的处理

    通过 Express 内置的 express.static 可以方便的托管静态文件,例如 img、css、js 文件等。

    app.use(express.static('public'));

    现在 public 目录下面的文件就可以访问了。

    例子:新建 13.js 文件:

    // 引入 express 框架
    const express = require('express');
    const path = require('path');
    // 创建网站服务器
    const app = express();
    
    app.use(express.static(path.join(__dirname, 'public')));
    
    // 监听端口
    app.listen(3000);
    console.log('网站服务器启动成功');

    在命令行工具输入:nodemon 13.js

    在浏览器中可以输入相应的地址,访问静态资源。比如:

    http://localhost:3000/images/1.jpg
    http://localhost:3000/css/base.css
    http://localhost:3000/default.html

    4、express-art-template 模板引擎

    4.1、模板引擎

    为了使 art-template 模板引擎能够更好的和 Express 框架配合,模板引擎官方在原 art-template 模板引擎的基础上封装了 express-art-template。

    同时安装这两个,使用 npm install art-template express-art-template 命令进行安装。

    语法:

    // 当渲染后缀为 art 的模板时,使用 express-art-template
    app.engine('art', require('express-art-template'));
    // 设置模板存放目录
    app.set('views', path.join(__dirname, 'views'));
    // 渲染模板时不写后缀,默认拼接 art 后缀
    app.set('view engine', 'art');
    app.get('/', (req, res) => {
      // 渲染模板
      res.render('index');
    })

    例子:

    在命令行工具中下载安装:

    npm install art-template express-art-template

    新建 14.js 文件:

    // 引入 express 框架
    const express = require('express');
    const path = require('path');
    // 创建网站服务器
    const app = express();
    
    // 1、告诉 express 框架使用什么模板引擎,渲染什么后缀的模板文件
    // 第1个参数是模板的后缀
    // 第2个参数是使用的模板引擎
    app.engine('art', require('express-art-template'));
    // 2、告诉 express 框架模板存放的位置是什么
    app.set('views', path.join(__dirname, 'views'));
    // 3、告诉 express 框架模板的默认后缀是什么
    app.set('view engine', 'art');
    
    app.get('/index', (req, res) => {
      // 拼接模板路径
      // 拼接模板后缀、
      // 那一个模板和那个数据进行拼接
      // 将拼接的结果响应给客户端
      res.render('index', {
        msg: 'message'
      })
    })
    
    // 监听端口
    app.listen(3000);
    console.log('网站服务器启动成功');

    在项目根目录下新建 views 文件夹,创建 index.art 文件:

    {{ msg }}

    在命令行工具中输入:nodemon 14.js

    在浏览器输入:http://localhost:3000/index ,可以看到:

    修改添加如下代码:

    // 引入 express 框架
    const express = require('express');
    const path = require('path');
    // 创建网站服务器
    const app = express();
    
    // 1、告诉 express 框架使用什么模板引擎,渲染什么后缀的模板文件
    // 第1个参数是模板的后缀
    // 第2个参数是使用的模板引擎
    app.engine('art', require('express-art-template'));
    // 2、告诉 express 框架模板存放的位置是什么
    app.set('views', path.join(__dirname, 'views'));
    // 3、告诉 express 框架模板的默认后缀是什么
    app.set('view engine', 'art');
    
    app.get('/index', (req, res) => {
      // 拼接模板路径
      // 拼接模板后缀、
      // 那一个模板和那个数据进行拼接
      // 将拼接的结果响应给客户端
      res.render('index', {
        msg: 'message'
      })
    })
    
    app.get('/list', (req, res) => {
      res.render('list', {
        msg: 'list page'
      })
    })
    
    // 监听端口
    app.listen(3000);
    console.log('网站服务器启动成功');

    在路篮球中输入:http://localhost:3000/list ,可以看到:

    4.2、app.locals 对象

    将变量设置到 app.locals 对象下面,这个数据在所有的模板中都可以获取到。

    示例代码:

    app.locals.users = [{
      name: '张三',
      age: 20
    },{
      name: '李四',
      age: 20
    }]

    例子:新建 15.js 文件:

    // 引入 express 框架
    const express = require('express');
    const path = require('path');
    // 创建网站服务器
    const app = express();
    
    // 模板配置
    app.engine('art', require('express-art-template'));
    app.set('views', path.join(__dirname, 'views'));
    app.set('view engine', 'art');
    
    app.locals.users = [{
      name: '张三',
      age: 20
    },{
      name: '李四',
      age: 30
    }]
    
    app.get('/index', (req, res) => {
      res.render('index', {
        msg: '首页'
      })
    })
    
    app.get('/list', (req, res) => {
      res.render('list', {
        msg: '列表页'
      })
    })
    
    // 监听端口
    app.listen(3000);
    console.log('网站服务器启动成功');

    打开 views 目录下的 index.art 和 list.art 文件,同时添加:

    {{ msg }}
    
    <ul>
      {{each users}}
      <li>
        {{$value.name}}
        {{$value.age}}
      </li>
      {{/each}}
    </ul>

    在命令行工具中输入:nodemon 15.js

    在浏览器输入:http://localhost:3000/index 和 http://localhost:3000/list ,可以看到:

    这就证明了 app.locals 这个对象下面的属性,我们在所有的模板中都可以拿到。所以我们可以把项目中一些公共数据,添加到 app.locals 这个对象下面。

    4.3、路由重定向 

    res.redirect('/admin/user');

    项目实例:博客项目

  • 相关阅读:
    内存的分页管理方式解释
    分组统计SQL
    NUMA导致的Oracle性能问题
    SQL Server死锁的解决过程
    PHP创建对象的6种方式
    PHP编程20大效率要点
    php设置随机ip访问
    php使用QueryList轻松采集JavaScript动态渲染页面
    正确理解 PHP 的重载
    PHP 核心特性之匿名函数
  • 原文地址:https://www.cnblogs.com/joe235/p/12915725.html
Copyright © 2011-2022 走看看