<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                [TOC] > 中間件(Middleware) 是一個函數,它可以訪問請求對象(request object (req)), 響應對象(response object (res)), 和 web 應用中處于請求-響應循環流程中的中間件,一般被命名為 next 的變量。 ## 中間件的功能 * 執行任何代碼。 * 修改請求和響應對象。 * 終結請求-響應循環。 * 調用堆棧中的下一個中間件。 * 如果當前中間件沒有終結請求-響應循環,則必須調用 next() 方法將控制權交給下一個中間件,否則請求就會掛起。 ## 中間件的類型 * 應用級中間件 * 路由級中間件 * 錯誤處理中間件 * 內置中間件 * 第三方中間件 ### 應用級中間件 應用級中間件綁定到 app 對象 使用 app.use() 和 app.METHOD(), 其中, METHOD 是需要處理的 HTTP 請求的方法,例如 GET, PUT, POST 等等,全部小寫。 ~~~ var app = express(); // 沒有掛載路徑的中間件,應用的每個請求都會執行該中間件 app.use(function (req, res, next) { console.log('Time:', Date.now()); next(); }); // 掛載至 /user/:id 的中間件,任何指向 /user/:id 的請求都會執行它 app.use('/user/:id', function (req, res, next) { console.log('Request Type:', req.method); next(); }); // 路由和句柄函數(中間件系統),處理指向 /user/:id 的 GET 請求 app.get('/user/:id', function (req, res, next) { res.send('USER'); }); ~~~ 作為中間件系統的路由句柄,使得為路徑定義多個路由成為可能。在下面的例子中,為指向 /user/:id 的 GET 請求定義了兩個路由。第二個路由雖然不會帶來任何問題,但卻永遠不會被調用,因為第一個路由已經終止了請求-響應循環。 ~~~ // 一個中間件棧,處理指向 /user/:id 的 GET 請求 app.get('/user/:id', function (req, res, next) { console.log('ID:', req.params.id); next(); }, function (req, res, next) { res.send('User Info'); }); // 處理 /user/:id, 打印出用戶 id app.get('/user/:id', function (req, res, next) { res.end(req.params.id); }); ~~~ 如果需要在中間件棧中跳過剩余中間件,調用 **next('route')** 方法將控制權交給下一個路由。 注意: next('route') 只對使用** app.VERB()** 或 **router.VERB()** 加載的中間件有效。 ~~~ // 一個中間件棧,處理指向 /user/:id 的 GET 請求 app.get('/user/:id', function (req, res, next) { // 如果 user id 為 0, 跳到下一個路由 if (req.params.id == 0) next('route'); // 否則將控制權交給棧中下一個中間件 else next(); // }, function (req, res, next) { // 渲染常規頁面 res.render('regular'); }); // 處理 /user/:id, 渲染一個特殊頁面 app.get('/user/:id', function (req, res, next) { res.render('special'); }); ~~~ ### 路由級中間件 路由級中間件和應用級中間件一樣,只是它綁定的對象為 express.Router()。 路由級使用 router.use() 或 router.VERB() 加載。 ~~~ var app = express(); var router = express.Router(); // 沒有掛載路徑的中間件,通過該路由的每個請求都會執行該中間件 router.use(function (req, res, next) { console.log('Time:', Date.now()); next(); }); // 一個中間件棧,顯示任何指向 /user/:id 的 HTTP 請求的信息 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(); }); // 一個中間件棧,處理指向 /user/:id 的 GET 請求 router.get('/user/:id', function (req, res, next) { // 如果 user id 為 0, 跳到下一個路由 if (req.params.id == 0) next('route'); // 負責將控制權交給棧中下一個中間件 else next(); // }, function (req, res, next) { // 渲染常規頁面 res.render('regular'); }); // 處理 /user/:id, 渲染一個特殊頁面 router.get('/user/:id', function (req, res, next) { console.log(req.params.id); res.render('special'); }); // 將路由掛載至應用 app.use('/', router); ~~~ ### 錯誤處理中間件 > 錯誤處理中間件有 **4** 個參數,定義錯誤處理中間件時必須使用這 4 個參數。即使不需要 next 對象,也必須在簽名中聲明它,否則中間件會被識別為一個常規中間件,不能處理錯誤。 > 中間件返回的響應是隨意的,可以響應一個 HTML 錯誤頁面、一句簡單的話、一個 JSON 字符串,或者其他任何您想要的東西。 為了便于組織(更高級的框架),您可能會像定義常規中間件一樣,定義多個錯誤處理中間件。比如您想為使用 XHR 的請求定義一個,還想為沒有使用的定義一個,那么: ~~~ var bodyParser = require('body-parser'); var methodOverride = require('method-override'); app.use(bodyParser()); app.use(methodOverride()); app.use(logErrors); app.use(clientErrorHandler); app.use(errorHandler); ~~~ logErrors 將請求和錯誤信息寫入標準錯誤輸出、日志或類似服務: ~~~ function logErrors(err, req, res, next) { console.error(err.stack); next(err); } ~~~ clientErrorHandler 的定義如下(注意這里將錯誤直接傳給了 next): ~~~ function clientErrorHandler(err, req, res, next) { if (req.xhr) { res.status(500).send({ error: 'Something blew up!' }); } else { next(err); } } ~~~ errorHandler 能捕獲所有錯誤,其定義如下: ~~~ function errorHandler(err, req, res, next) { res.status(500); res.render('error', { error: err }); } ~~~ 如果**向 next() 傳入參數(除了 ‘route’ 字符串)**,Express 會認為當前請求有錯誤的輸出,因此跳過后續其他非錯誤處理和路由/中間件函數。如果需做特殊處理,需要創建新的錯誤處理路由。 如果路由句柄有多個回調函數,可使用 ‘route’ 參數跳到下一個路由句柄。比如: ~~~ app.get('/a_route_behind_paywall', function checkIfPaidSubscriber(req, res, next) { if(!req.user.hasPaid) { // 繼續處理該請求 next('route'); } }, function getPaidContent(req, res, next) { PaidContent.find(function(err, doc) { if(err) return next(err); res.json(doc); }); }); app.get('/a_route_behind_paywall', function(err, req, res, next) { console.error(err.stack); res.status(500).send('Something broke!'); } ) ~~~ **缺省錯誤處理句柄** Express 內置了一個錯誤處理句柄,它可以捕獲應用中可能出現的任意錯誤。這個缺省的錯誤處理中間件將被添加到中間件堆棧的底部。 如果你向 next() 傳遞了一個 error ,而你并沒有在錯誤處理句柄中處理這個 error,Express 內置的缺省錯誤處理句柄就是最后兜底的。最后錯誤將被連同堆棧追蹤信息一同反饋到客戶端。堆棧追蹤信息并不會在生產環境中反饋到客戶端。 > 設置環境變量 NODE_ENV 為 “production” 就可以讓應用運行在生產環境模式下。 如果你已經開始向 response 輸出數據了,這時才調用 next() 并傳遞了一個 error,比如你在將向客戶端輸出數據流時遇到一個錯誤,Express 內置的缺省錯誤處理句柄將幫你關閉連接并告知 request 請求失敗。 因此,當你添加了一個自定義的錯誤處理句柄后,如果已經向客戶端發送包頭信息了,你還可以將錯誤處理交給 Express 內置的錯誤處理機制。 ~~~ function errorHandler(err, req, res, next) { if (res.headersSent) { return next(err); } res.status(500); res.render('error', { error: err }); } ~~~ ## 內置中間件 express.static(root, [options]) express.static 是 Express 唯一內置的中間件。它基于 serve-static,負責在 Express 應用中提托管靜態資源。 參數 root 指提供靜態資源的根目錄。 可選的 options 參數擁有如下屬性。 屬性 | 描述 | 類型 | 缺省值 | | --- | --- | --- | --- | dotfiles | 是否對外輸出文件名以點(.)開頭的文件。可選值為 “allow”、“deny” 和 “ignore” | String | “ignore” etag | 是否啟用 etag 生成 | Boolean | true extensions | 設置文件擴展名備份選項 | Array | [] index | 發送目錄索引文件,設置為 false 禁用目錄索引。 | Mixed |“index.html” lastModified | 設置 Last-Modified 頭為文件在操作系統上的最后修改日期。可能值為 true 或 false。 | Boolean | true maxAge | 以毫秒或者其字符串格式設置 Cache-Control 頭的 max-age 屬性。 | Number | 0 redirect | 當路徑為目錄時,重定向至 “/”。 | Boolean | true setHeaders | 設置 HTTP 頭以提供文件的函數。 | Function | ~~~ var options = { dotfiles: 'ignore', etag: false, extensions: ['htm', 'html'], index: false, maxAge: '1d', redirect: false, setHeaders: function (res, path, stat) { res.set('x-timestamp', Date.now()); } } app.use(express.static('public', options)); ~~~ 每個應用可有多個靜態目錄。 ~~~ app.use(express.static('public')); app.use(express.static('uploads')); app.use(express.static('files')); ~~~ ## 第三方中間件 安裝所需功能的 node 模塊,并在應用中加載,可以在應用級加載,也可以在路由級加載。 ~~~ $ npm install cookie-parser var express = require('express'); var app = express(); var cookieParser = require('cookie-parser'); // 加載用于解析 cookie 的中間件 app.use(cookieParser()); ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看