express框架安裝及中間件原理

本文主要介紹express中間件的原理,來應對面試。

一、安裝express及初始化: 

  npm install express-generator -g   =>   express express-test   =>  npm install & npm start   => 在bin文件夾中的www.js文件中能夠看到訪問的端口是3000,經過瀏覽器訪問localhost:3000。html

  爲了方便開發及調試,咱們還須要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 devnode

 

二、目錄介紹:

  bin/www.js:  建立http服務面試

  public: 靜態文件目錄,單純開發接口的話,此目錄能夠忽略。express

  routes: 存放路由文件。npm

  views: 存放html模板,忽略。json

 

三、app.js(重要):

  下面是代碼,我作了一些註釋:api

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;

四、處理路由(重要):

  路由是什麼?請本身百度!瀏覽器

  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,設置方法以下:

能夠看到這裏返回了咱們設置的數據。

五、關於中間件的理解(重中之重):

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

咱們先來分析一下從瀏覽器地址欄輸入url到客戶端顯示數據之間這個過程到底發生了什麼?

瀏覽器向服務器發送一個請求後,服務器直接經過request.定位屬性的方式獲得經過request攜帶過去的數據(有用戶輸入的數據和瀏覽器自己的數據信息)。這中間就必定有一個函數將這些數據分類作了處理,已經處理好了,最後讓request對象調用使用,對的,這個處理數據處理函數就是咱們要說的 中間件 。因而可知,中間件能夠總結如下幾點:

一、封裝了一些處理一個完整事件的功能函數。

二、非內置的中間件須要經過安裝後,require到文件就能夠運行。

三、封裝了一些或許複雜但確定是通用的功能。

光說可能不太懂,看代碼你就知道了!

這是一個驗證登陸的函數:

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(),返回「登錄成功」。這只是些簡單的理解,詳情請看大佬博客http://www.javashuo.com/article/p-vlzlvzxj-hp.html

相關文章
相關標籤/搜索