美文网首页
NodeJs 网络框架 express

NodeJs 网络框架 express

作者: yangweigbh | 来源:发表于2017-02-01 13:19 被阅读173次

    安装

    npm install express --save

    运行

    var express = require('express')
    var app = express()
    
    app.get('/', function (req, res) {
      res.send('Hello World!')
    })
    
    app.listen(3000, function () {
      console.log('Example app listening on port 3000!')
    })
    

    生成模板工程

    安装express-generator

    npm install express-generator -g

    生成模板

    express --view=jade myapp

    安装依赖库

    cd myapp && npm install

    运行

    DEBUG=myapp:* npm start

    windows: set DEBUG=myapp:* & npm start

    生成文件目录结构

    Paste_Image.png

    Serving静态文件

    app.use(express.static('public'))
    
    http://localhost:3000/images/kitten.jpg
    http://localhost:3000/css/style.css
    http://localhost:3000/js/app.js
    http://localhost:3000/images/bg.png
    http://localhost:3000/hello.html
    

    Serve多个文件夹

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

    serve 到不同的路径

    app.use('/static', express.static('public'))
    
    http://localhost:3000/static/images/kitten.jpg
    http://localhost:3000/static/css/style.css
    http://localhost:3000/static/js/app.js
    http://localhost:3000/static/images/bg.png
    http://localhost:3000/static/hello.html
    

    Route

    // GET method route
    app.get('/', function (req, res) {
      res.send('GET request to the homepage')
    })
    
    // POST method route
    app.post('/', function (req, res) {
      res.send('POST request to the homepage')
    })
    

    支持的HTTP方法:

    get, post, put, head, delete, options, trace, copy, lock, mkcol, move, purge, propfind, proppatch, unlock, report, mkactivity, checkout, merge, m-search, notify, subscribe, unsubscribe, patch, search, and connect.

    app.all()对特定路径的所有请求方法都会调用。通常用来实现中间件

    app.all('/secret', function (req, res, next) {
      console.log('Accessing the secret section ...')
      next() // pass control to the next handler
    })
    

    path 接受正则表达式

    request path 参数

    app.get('/users/:userId/books/:bookId', function (req, res) {
      res.send(req.params)
    })
    

    Route path: /users/:userId/books/:bookId
    Request URL: http://localhost:3000/users/34/books/8989
    req.params: { "userId": "34", "bookId": "8989" }

    同一路径的request handler可以设置多个

    app.get('/example/b', function (req, res, next) {
      console.log('the response will be sent by the next function ...')
      next()
    }, function (req, res) {
      res.send('Hello from B!')
    })
    

    也可以通过数组设置

    var cb0 = function (req, res, next) {
      console.log('CB0')
      next()
    }
    
    var cb1 = function (req, res, next) {
      console.log('CB1')
      next()
    }
    
    var cb2 = function (req, res) {
      res.send('Hello from C!')
    }
    
    app.get('/example/c', [cb0, cb1, cb2])
    
    

    app.route()将同一路径的不同方法的handler做链式定义

    app.route('/book')
      .get(function (req, res) {
        res.send('Get a random book')
      })
      .post(function (req, res) {
        res.send('Add a book')
      })
      .put(function (req, res) {
        res.send('Update the book')
      })
    

    express.Router定义模块化的router

    var express = require('express')
    var router = express.Router()
    
    // middleware that is specific to this router
    router.use(function timeLog (req, res, next) {
      console.log('Time: ', Date.now())
      next()
    })
    // define the home page route
    router.get('/', function (req, res) {
      res.send('Birds home page')
    })
    // define the about route
    router.get('/about', function (req, res) {
      res.send('About birds')
    })
    
    module.exports = router
    

    Middleware

    Express本身没有多少功能,主要功能是由各种middleware来实现的

    Middleware 由接受req,res和next(可选)参数的函数实现。

    Middleware可以:

    • 执行代码
    • 修改req和res
    • 结束req-res cycle
    • 执行下一个middleware

    如果一个middleware没有结束req-res cycle,则要调用next来执行下一个middleware

    有5种middleware

    • Application-level middleware

    app.use() and app.METHOD()设置application-level middleware

    • Router-level middleware

    设置在Router上的middleware

    var app = express()
    var router = express.Router()
    
    // a middleware function with no mount path. This code is executed for every request to the router
    router.use(function (req, res, next) {
      console.log('Time:', Date.now())
      next()
    })
    
    // a middleware sub-stack shows request info for any type of HTTP request to the /user/:id path
    router.use('/user/:id', function (req, res, next) {
      console.log('Request URL:', req.originalUrl)
      next()
    }, function (req, res, next) {
      console.log('Request Type:', req.method)
      next()
    })
    
    // a middleware sub-stack that handles GET requests to the /user/:id path
    router.get('/user/:id', function (req, res, next) {
      // if the user ID is 0, skip to the next router
      if (req.params.id === '0') next('route')
      //跳转到下一个matching route function
      else next() // 跳转到同一个Route function的下一个handler
    }, function (req, res, next) {
      // render a regular page
      res.render('regular')
    })
    
    // handler for the /user/:id path, which renders a special page
    router.get('/user/:id', function (req, res, next) {
      console.log(req.params.id)
      res.render('special')
    })
    
    // mount the router on the app
    app.use('/', router)
    
    • Error-handling middleware
      函数签名为(err, req, res, next)
    app.use(function (err, req, res, next) {
      console.error(err.stack)
      res.status(500).send('Something broke!')
    })
    
    • Built-in middleware

    express.static(root, [options])

    • Third-party middleware

    通过npm安装,然后在application-level使用

    npm install cookie-parser

    var cookieParser = require('cookie-parser')
    
    // load the cookie-parsing middleware
    app.use(cookieParser())
    

    Error handle

    可以定义多个error handler,前一个handler通过调用next(err)来调用下一个error handler

    app.use(logErrors)
    app.use(clientErrorHandler)
    app.use(errorHandler)
    
    function logErrors (err, req, res, next) {
      console.error(err.stack)
      next(err)
    }
    
    function clientErrorHandler (err, req, res, next) {
      if (req.xhr) {
        res.status(500).send({ error: 'Something failed!' })
      } else {
        next(err)
      }
    }
    
    function errorHandler (err, req, res, next) {
      res.status(500)
      res.render('error', { error: err })
    }
    

    如果在request handler中调用next时传入非"route"的参数,则会认为产生了错误,会跳过剩下的request handler,调用error handler

    如果error handler没有调用next,则要负责生产response,否则request会hang住,无法垃圾回收

    Express 有一个默认的error handler,会将错误的堆栈输出到client,production环境下不输出堆栈。

    当在最后一个自定义的error handler中调用next(err)时,会委托给默认error handler处理。

    相关文章

      网友评论

          本文标题:NodeJs 网络框架 express

          本文链接:https://www.haomeiwen.com/subject/fezkittx.html