Expressフレームワークのnext()が原因のエラーエラー:送信後にヘッダーを設定できません。



Error Caused Next Express Framework Error



サーバーに同じパスでサーバーを処理する2つのメソッドがある場合、一致する最初のメソッドのみが実行され、残りは無視されます。
同じルートで複数のメソッドを処理する場合は、nextを使用する必要があります。

次は、エクスプレスミドルウェア関数の3番目のパラメーターです。次の機能の主な機能は、制御を次のミドルウェアに移すことです。現在のミドルウェアがリクエストを終了せず、次に呼び出さない場合、リクエストは一時停止されます。作品は実行されません。



具体的なテストコードは次のとおりです。
Expressサーバーコードのindex.jsに次のテストコードを追加します。

router.get('/users/nextTest', function (req,res,next) { res.send('index.js get') //next() })

次のようにusers.jsにコードを追加します



router.get('/nextTest', function (req,res,next) { console.log('users nextTest') })

next()に注釈が付けられていない場合、user.jsミドルウェアを実行できます。 next()が呼び出されない場合、users.jsのミドルウェアは実行されません。
res.send( 'index.js get')がuser.jsのプロキシに移動され、next()を呼び出さない場合、リクエストはサーバーからの応答を取得しません。つまり、リクエストは一時停止されます。

index.js router.get('/users/nextTest', function (req,res,next) { // res.send('index.js get') console.log('index.js get') // next() }) users.js router.get('/nextTest', function (req,res,next) { console.log('users nextTest') res.send('users nextTest') })

定義されたミドルウェアがリクエストを終了する場合は、次の関数を呼び出さないでください。呼び出さないと問題が発生する可能性があります。

index.js router.get('/users/nextTest', function (req,res,next) { res.end('index.js get') Next()// can be called normally }) users.js router.get('/nextTest', function (req,res,next) { console.log('users nextTest') //res.send('users nextTest') Next() // Here the request is over, you can't call next again. })

サーバーは次のエラーを報告します:送信後にヘッダーを設定できません。:



GET /users/nextTest 200 4.541 ms - - users nextTest Error: Can't set headers after they are sent. at validateHeader (_http_outgoing.js:491:11) at ServerResponse.setHeader (_http_outgoing.js:498:3) at ServerResponse.header (D: ode.jsmyMongooseExpress ode_modulesexpresslib esponse.js:767:10) at ServerResponse.contentType (D: ode.jsmyMongooseExpress ode_modulesexpresslib esponse.js:595:15) at ServerResponse.send (D: ode.jsmyMongooseExpress ode_modulesexpresslib esponse.js:145:14) at done (D: ode.jsmyMongooseExpress ode_modulesexpresslib esponse.js:1004:10) at Object.exports.renderFile (D: ode.jsmyMongooseExpress ode_modulespuglibindex.js:412:12) at View.exports.__express [as engine] (D: ode.jsmyMongooseExpress ode_modulespuglibindex.js:455:11) at View.render (D: ode.jsmyMongooseExpress ode_modulesexpresslibview.js:135:8) at tryRender (D: ode.jsmyMongooseExpress ode_modulesexpresslibapplication.js:640:10) at Function.render (D: ode.jsmyMongooseExpress ode_modulesexpresslibapplication.js:592:3) at ServerResponse.render (D: ode.jsmyMongooseExpress ode_modulesexpresslib esponse.js:1008:7) at D: ode.jsmyMongooseExpressapp.js:41:7 at Layer.handle_error (D: ode.jsmyMongooseExpress ode_modulesexpresslib outerlayer.js:71:5) at trim_prefix (D: ode.jsmyMongooseExpress ode_modulesexpresslib outerindex.js:315:13) at D: ode.jsmyMongooseExpress ode_modulesexpresslib outerindex.js:284:7

例外をスローする理由:users.jsのミドルウェアでのリクエストは終了しましたが、次の関数が呼び出され、次のコードは引き続き実行されますが、実際にはリクエストは終了しましたが、ミドルウェアは引き続きヘッドを試みます。 to res属性値を追加または変更して、この例外が報告されるようにします。

// 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 : {} // render the error page res.status(err.status || 500) res.render('error') })

次の関数には、内部にwhileループがあります。各ループはスタックからレイヤーを取得します。このレイヤーにはルーティングとミドルウェアの情報が含まれており、レイヤーと要求されたパスに一致します。一致が成功すると、レイヤーが実行されます。 .handle_request、ミドルウェア関数と呼ばれます。ただし、一致が失敗した場合、次のレイヤー(つまりミドルウェア)がループします。

これで、上記の質問を説明できます。カスタムミドルウェアで次の関数が呼び出されないのに、要求された '/ xxx'が登録済みの '/ a'ルーティングミドルウェアと一致しないため、404ミドルウェアは後で実行されます。 whileループは引き続き実行され、一致する404ミドルウェアが成功するため、404ミドルウェアが実行されます。

この記事の参照先: https://cnodejs.org/topic/5757e80a8316c7cb1ad35bab

転載:https://www.jianshu.com/p/8923d830eb83