express框架安装及中间件原理

本文主要介绍express中间件的原理,来应对面试。

1、安装express及初始化: 

  npm install express-generator -g   =>   express express-test   =>  npm install & npm start   => 在bin文件夹中的www.js文件中可以看到访问的端口是3000,通过浏览器访问localhost:3000。

  为了方便开发及调试,我们还需要npm i nodemon cross-env --save-dev,其中cross-env用来设置环境变量的参数,nodemon用来监听文件的变化,这样我们修改代码的时候就不需要每次手动重启服务,可以避免产生一些非预期的错误。安装好这两个插件之后,打开package.json文件,在scripts中添加以下代码:

"dev": "cross-env NODE_ENV=dev nodemon ./bin/www.js"
{
  "name": "blog-express",
  "version": "0.0.0",
  "private": true,
  "scripts": {
    "start": "node ./bin/www",
    "dev": "cross-env NODE_ENV=dev nodemon ./bin/www.js"
  },
  "dependencies": {
    "cookie-parser": "~1.4.4",
    "debug": "~2.6.9",
    "express": "~4.16.1",
    "http-errors": "~1.6.3",
    "jade": "~1.11.0",
    "morgan": "~1.9.1"
  },
  "devDependencies": {
    "cross-env": "^6.0.3",
    "nodemon": "^2.0.2"
  }
}

保存好之后,命令行运行npm run dev

2、目录介绍:

  bin/www.js:  创建http服务

  public: 静态文件目录,单纯开发接口的话,此目录可以忽略。

  routes: 存放路由文件。

  views: 存放html模板,忽略。

3、app.js(重要):

  下面是代码,我做了一些注释:

var createError = require('http-errors');    //处理报错信息模块
var express = require('express');      //引用express框架
var path = require('path');            //提供了一些用于处理文件路径的小工具
var cookieParser = require('cookie-parser');      //解析cookie
var logger = require('morgan');              //记录access log生成日志

var indexRouter = require('./routes/index');   //引用路由
var usersRouter = require('./routes/users');

var app = express();       //初始化app

// view engine setup 
app.set('views', path.join(__dirname, 'views'));    //前端模板处理,不用管可以注释
app.set('view engine', 'jade');

//注册各种功能
app.use(logger('dev'));
app.use(express.json());      //处理post过来的data 路由中直接用req.body来获取 用来获取content-type = application/json格式的数据
app.use(express.urlencoded({ extended: false }));    //处理表单提交过来的数据 content-type = x-www-form-urlencoded格式
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));    //不用管可以注释

app.use('/', indexRouter);      //注册路由   '/' 目的是与路由文件中的path进行拼接,如:路由文件中的path是/user
app.use('/users', usersRouter);   // 这里的path '/users' 目的是与路由文件中的path进行拼接,如:路由文件中的path是/list  最后访问的地址就为/user/list

// catch 404 and forward to error handler
app.use(function(req, res, next) {      //检测404
  next(createError(404));
});

// error handler
app.use(function(err, req, res, next) {    //抛出服务端报错
  // set locals, only providing error in development
  res.locals.message = err.message;
  //res.locals.error = req.app.get('env') === 'development' ? err : {};
  res.locals.error = req.app.get('env') === 'dev' ? err : {};   //因为在package.json中设置的环境变量是dev,所以这里做了修改

  // render the error page
  res.status(err.status || 500);
  res.render('error');
});

module.exports = app;

4、处理路由(重要):

  路由是什么?请自己百度!

  1)get请求:

在routes文件夹中新建blog.js文件,编写代码

var express = require('express');
var router = express.Router();

router.get('/list', function(req, res, next) {
    res.json({
        errno: 0,
        data: [1, 2, 3]
    })
});

module.exports = router;

写好之后,编写app.js:   

const blogRouter = require('./routes/blog')    //定义路由
app.use('/api/blog', blogRouter)   //注册路由
访问localhost:3000/api/blog/list,可以看到我们定义的返回值正确的打印在浏览器中。
其中,res.json({})  可以解析并返回json字符串,原生实现大致原理是:res.end(JSON.stringify(userData))。另外它还可以自动设置返回的头信息为json格式,原生实现大致原理: res.setHeader('Content-type', 'application/json')
   2 )post请求
在blog.js文件中,编写代码:
router.post('/login', function(req, res, next) {
    const { username, password } = req.body    //因为应用了express.json(),所以可以直接从req.body中获取postdata
    res.json({
        errno: 0,
        data: {
            username,
            password
        }
    })
});

打开postman,访问http://localhost:3000/api/blog/login,设置方法如下:

可以看到这里返回了我们设置的数据。

5、关于中间件的理解(重中之重):

  以下文字是转载某大佬的博客(博客地址:https://blog.csdn.net/huang100qi/article/details/80220012):

我们先来分析一下从浏览器地址栏输入url到客户端显示数据之间这个过程到底发生了什么?

浏览器向服务器发送一个请求后,服务器直接通过request.定位属性的方式得到通过request携带过去的数据(有用户输入的数据和浏览器本身的数据信息)。这中间就一定有一个函数将这些数据分类做了处理,已经处理好了,最后让request对象调用使用,对的,这个处理数据处理函数就是我们要说的 中间件 。由此可见,中间件可以总结以下几点:

1、封装了一些处理一个完整事件的功能函数。

2、非内置的中间件需要通过安装后,require到文件就可以运行。

3、封装了一些或许复杂但肯定是通用的功能。

光说可能不太懂,看代码你就知道了!

这是一个验证登录的函数:

module.exports = (req, res, next) => {
    if (req.session.username) {
        next()
        return
    }
    res.json({
        data: '未登录'
    })
}

然后在路由函数中作为参数传入:

router.post('/new', loginCheck, (req, res, next) => {
    req.body.author = req.session.username
    const result = newBlog(req.body)
    return result.then(data => {
        res.json({
            data: '登陆成功'
        })
    })
})

这个loginCheck就是中间件。如果验证成功,就执行next(),返回“登陆成功”。这只是些简单的理解,详情请看大佬博客https://www.cnblogs.com/houfee/p/10366082.html

        

 

猜你喜欢

转载自www.cnblogs.com/Layee/p/12101444.html