エラー:ヘッダーがクライアントに送信された後にヘッダーを設定できません


724

私はNode.jsにかなり慣れていないので、いくつか問題があります。

Node.js 4.10とExpress 2.4.3を使用しています。

http://127.0.0.1:8888/auth/facebookにアクセスしようとすると、http://127.0.0.1:8888/auth/facebook_callbackにリダイレクトされます

次に、次のエラーを受け取りました。

Error: Can't render headers after they are sent to the client.
    at ServerResponse.<anonymous> (http.js:573:11)
    at ServerResponse._renderHeaders (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/patch.js:64:25)
    at ServerResponse.writeHead (http.js:813:20)
    at /home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect-auth/lib/auth.strategies/facebook.js:28:15
    at /home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect-auth/lib/index.js:113:13
    at next (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect-auth/lib/strategyExecutor.js:45:39)
    at [object Object].pass (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect-auth/lib/authExecutionScope.js:32:3)
    at [object Object].halt (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect-auth/lib/authExecutionScope.js:29:8)
    at [object Object].redirect (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect-auth/lib/authExecutionScope.js:16:8)
    at [object Object].<anonymous> (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect-auth/lib/auth.strategies/facebook.js:77:15)
Error: Can't set headers after they are sent.
    at ServerResponse.<anonymous> (http.js:527:11)
    at ServerResponse.setHeader (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/patch.js:50:20)
    at next (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/http.js:162:13)
    at next (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/http.js:195:11)
    at next (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/http.js:150:23)
    at param (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/middleware/router.js:189:13)
    at pass (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/middleware/router.js:191:10)
    at Object.router [as handle] (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/middleware/router.js:197:6)
    at next (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/http.js:198:15)
    at Object.auth [as handle] (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect-auth/lib/index.js:153:7)
Error: Can't set headers after they are sent.
    at ServerResponse.<anonymous> (http.js:527:11)
    at ServerResponse.setHeader (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/patch.js:50:20)
    at next (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/http.js:162:13)
    at next (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/http.js:207:9)
    at next (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/http.js:150:23)
    at param (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/middleware/router.js:189:13)
    at pass (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/middleware/router.js:191:10)
    at Object.router [as handle] (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/middleware/router.js:197:6)
    at next (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/http.js:198:15)
    at Object.auth [as handle] (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect-auth/lib/index.js:153:7)
Error: Can't set headers after they are sent.
    at ServerResponse.<anonymous> (http.js:527:11)
    at ServerResponse.setHeader (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/patch.js:50:20)
    at next (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/http.js:162:13)
    at next (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/http.js:150:23)
    at next (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/http.js:207:9)
    at Object.auth [as handle] (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect-auth/lib/index.js:153:7)
    at next (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/http.js:198:15)
    at HTTPServer.handle (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/http.js:211:3)
    at Object.handle (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/http.js:105:14)
    at next (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/http.js:198:15)
Error: Can't set headers after they are sent.
    at ServerResponse.<anonymous> (http.js:527:11)
    at ServerResponse.setHeader (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/patch.js:50:20)
    at next (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/http.js:162:13)
    at next (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/http.js:150:23)
    at next (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/http.js:207:9)
    at HTTPServer.handle (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/http.js:211:3)
    at Object.handle (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/http.js:105:14)
    at next (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/http.js:198:15)
    at /home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/middleware/session.js:323:9
    at /home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/middleware/session.js:338:9

node.js:134
        throw e; // process.nextTick error, or 'error' event on first tick
        ^
Error: Can't set headers after they are sent.
    at ServerResponse.<anonymous> (http.js:527:11)
    at ServerResponse.setHeader (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/patch.js:50:20)
    at next (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/http.js:162:13)
    at next (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/http.js:207:9)
    at /home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/middleware/session.js:323:9
    at /home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/middleware/session.js:338:9
    at Array.<anonymous> (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/middleware/session/memory.js:57:7)
    at EventEmitter._tickCallback (node.js:126:26)

以下は私のコードです:

var fbId= "XXX";
var fbSecret= "XXXXXX";
var fbCallbackAddress= "http://127.0.0.1:8888/auth/facebook_callback"

var cookieSecret = "node";     // enter a random hash for security

var express= require('express');
var auth = require('connect-auth')
var app = express.createServer();


app.configure(function(){
    app.use(express.bodyParser());
    app.use(express.methodOverride());
    app.use(express.cookieParser());
    app.use(express.session({secret: cookieSecret}));
    app.use(auth([
        auth.Facebook({
            appId : fbId,
            appSecret: fbSecret,
            callback: fbCallbackAddress,
            scope: 'offline_access,email,user_about_me,user_activities,manage_pages,publish_stream',
            failedUri: '/noauth'
        })
    ]));
    app.use(app.router);
});


app.get('/auth/facebook', function(req, res) {
  req.authenticate("facebook", function(error, authenticated) {
    if (authenticated) {
      res.redirect("/great");
      console.log("ok cool.");
      console.log(res['req']['session']);
    }
  });
});

app.get('/noauth', function(req, res) {
  console.log('Authentication Failed');
  res.send('Authentication Failed');
});

app.get('/great', function( req, res) {
  res.send('Supercoolstuff');
});

app.listen(8888);

私のコードの何が問題になっていますか?


visionmediaからの簡単な回答:github.com/visionmedia/express/issues/634
shi11i

2
Googleからこの質問に送られましたが、ExpressJSの新しいバージョンにはres.headersSentブール値があり、ヘッダーを設定/送信しても安全かどうかを確認できます
Julian Soro

回答:


1112

resExpress のオブジェクトはNode.jsのhttp.ServerResponseサブクラスです(http.jsソースを参照)。電話をかけるres.setHeader(name, value)まで、何度でも電話をかけることができますres.writeHead(statusCode)。その後writeHead、ヘッダーが組み込まれ、呼び出すことができるのはres.write(data)最終的にres.end(data)です。

エラー「エラー:送信後にヘッダーを設定できません。」はすでにBodyまたはFinished状態にありますが、一部の関数がヘッダーまたはstatusCodeを設定しようとしました。このエラーが表示された場合は、本文の一部がすでに書き込まれた後にヘッダーを送信しようとするものを探してください。たとえば、誤って2回呼び出されたコールバックや、本文の送信後に発生したエラーを探します。

あなたのケースでは、あなたはを呼び出しましたres.redirect()、それが応答を完了にさせました。次に、コードがエラーをスローしました(res.reqis null)。エラーは実際のfunction(req, res, next)(コールバック内ではなく)内で発生したため、Connectはそれをキャッチし、500エラーページを送信しようとしました。しかし、ヘッダーはすでに送信されているので、Node.js setHeaderは見たエラーをスローしました。

Node.js / Express応答メソッドの包括的なリストと、それらを呼び出す必要がある場合:

応答でなければなりませんヘッドとのままヘッド

  1. res.writeContinue()
  2. res.statusCode = 404
  3. res.setHeader(name, value)
  4. res.getHeader(name)
  5. res.removeHeader(name)
  6. res.header(key[, val]) (エクスプレスのみ)
  7. res.charset = 'utf-8' (Expressのみ。Express固有のメソッドにのみ影響します)
  8. res.contentType(type) (エクスプレスのみ)

応答である必要がありますとなり、ボディ

  1. res.writeHead(statusCode, [reasonPhrase], [headers])

レスポンスはどちらかにすることができヘッド/ボディ内や遺跡ボディ

  1. res.write(chunk, encoding='utf8')

レスポンスはどちらかにすることができヘッド/ボディとなり、完成

  1. res.end([data], [encoding])

応答はヘッド/ボディのいずれかであり、現在の状態のままです。

  1. res.addTrailers(headers)

応答である必要がありますとなり、完成

  1. return next([err]) (接続/エクスプレスのみ)
  2. ミドルウェア内の例外function(req, res, next)(Connect / Expressのみ)
  3. res.send(body|status[, headers|status[, status]]) (エクスプレスのみ)
  4. res.attachment(filename) (エクスプレスのみ)
  5. res.sendfile(path[, options[, callback]]) (エクスプレスのみ)
  6. res.json(obj[, headers|status[, status]]) (エクスプレスのみ)
  7. res.redirect(url[, status]) (エクスプレスのみ)
  8. res.cookie(name, val[, options]) (エクスプレスのみ)
  9. res.clearCookie(name[, options]) (エクスプレスのみ)
  10. res.render(view[, options[, fn]]) (エクスプレスのみ)
  11. res.partial(view[, options]) (エクスプレスのみ)

13
うん、next()または他のcbを2回呼び出すことを確認します。
トニーグティエレス2015年

3
Expressリンクが機能していないようです
Korhan Ozturk、2015

25
また、この典型的な間違いにも注意してください。res.redirect()はステートメントの実行を停止しません...したがって、その後に戻ります。そうしないと、他のコードが実行され、有名なヘッダーエラーが発生する可能性があります。説明ありがとうございます!
KLoozen

これを回避するには、通常、コールバックの最後にreturnを使用することをお勧めします
thethakuri

4
ミドルウェアで非常に小さなエラーを発生させましたが、return以前next()はエラーを発生させていませんでした。おかげでエラーが発生しました!
illcrx 2016

113

このエラーにもしばらく遭遇しました。私は(希望)私はそれを頭で覆ったと思います、参照のためにここに書きたかったのです。

メソッドを使用してミドルウェアを接続または表現するために(接続に組み込まれている)app.use追加するとServer.prototype.stack、項目が接続に追加されます(少なくとも、現在のnpm install connect。サーバーはリクエストを受け取ると、スタックを反復処理して(request, response, next)メソッドを呼び出します。

問題は、ミドルウェア項目の1つで応答の本文またはヘッダーに書き込みが行われた場合(何らかの理由で/または何らかの理由で呼び出されたように見える)に呼び出されずresponse.end()next()、コアServer.prototype.handleメソッドが完了すると呼び出されて気づくはずです。それ:

  1. スタックにアイテムがなくなった、および/または
  2. それresponse.headerSentは本当です。

したがって、エラーがスローされます。しかし、それがスローするエラーは、(接続http.jsソースコードからの)この基本的な応答だけです:

res.statusCode = 404;
res.setHeader('Content-Type', 'text/plain');
res.end('Cannot ' + req.method + ' ' + req.url);

すぐそこにres.setHeader('Content-Type', 'text/plain');あります。response.end()を呼び出さずに、renderメソッドで設定している可能性があります。

response.setHeader("Content-Type", "text/html");
response.write("<p>Hello World</p>");

すべてを構造化する必要がある方法は次のとおりです。

良いミドルウェア

// middleware that does not modify the response body
var doesNotModifyBody = function(request, response, next) {
  request.params = {
    a: "b"
  };
  // calls next because it hasn't modified the header
  next();
};

// middleware that modify the response body
var doesModifyBody = function(request, response, next) {
  response.setHeader("Content-Type", "text/html");
  response.write("<p>Hello World</p>");
  response.end();
  // doesn't call next()
};

app.use(doesNotModifyBody);
app.use(doesModifyBody);

問題のあるミドルウェア

var problemMiddleware = function(request, response, next) {
  response.setHeader("Content-Type", "text/html");
  response.write("<p>Hello World</p>");
  next();
};

問題のあるミドルウェアは、response.end()やを呼び出さずに応答ヘッダーを設定next()するため、接続のサーバーが混乱します。


7
+1これはすばらしい説明ですが、res.redirect()を使用する場合はどうでしょうか?ミドルウェアがなんらかの条件に基づいてリダイレクトしようとすると、この問題に頻繁に遭遇します。「良いミドルウェア」の例では、ミドルウェアはリダイレクトすべきではありませんか?
qodeninja

あなたは問題のあるミドルウェアと呼ばれるもののためにこの正確な問題があることを知っていますが、応答を返しますが、チェーンの一部として別のコントローラーでさらに処理したい場合は、このエラーを抑制する方法を教えてください?
iQ。

57

このQ&Aの回答の一部が間違っています。受け入れられた回答もあまり「実用的」ではないので、より簡単に説明した回答を掲載したいと思います。私の回答は、何度も何度も投稿されたエラーの99%をカバーします。エラーの背後にある実際の理由のために、受け入れられた答えを見てください。


HTTPは、リクエストごとに1つの応答が必要なサイクルを使用します。クライアントが要求(例:POSTまたはGET)を送信するとき、サーバーはそれに1つの応答のみを送信します。

このエラーメッセージ:

エラー:送信後にヘッダーを設定できません。

通常、1つの要求に対して複数の応答を送信すると発生します。次の関数がリクエストごとに1回だけ呼び出されるようにしてください。

  • res.json()
  • res.send()
  • res.redirect()
  • res.render()

(およびめったに使用されないいくつか、受け入れられた答えを確認してください)

これらのres関数が呼び出されても、ルートコールバックは返されません。関数またはreturnステートメントの最後に到達するまで実行を続けます。応答を送信するときに戻りたい場合は、次のようにできますreturn res.send()


たとえば、次のコードを見てください。

app.post('/api/route1', function(req, res) {
  console.log('this ran');
  res.status(200).json({ message: 'ok' });
  console.log('this ran too');
  res.status(200).json({ message: 'ok' });
}

POSTリクエストが/ api / route1に送信されると、コールバックのすべての行が実行されます。A 彼らが送られた後、缶は、ヘッダーを設定されていないため、エラーメッセージがスローされますres.json()2つの応答が送信される意味、二回と呼ばれています。

リクエストごとに送信できる応答は1つだけです。


上記のコードサンプルのエラーは明らかでした。より一般的な問題は、いくつかのブランチがある場合です。

app.get('/api/company/:companyId', function(req, res) {
  const { companyId } = req.params;
  Company.findById(companyId).exec((err, company) => {
      if (err) {
        res.status(500).json(err);
      } else if (!company) {
        res.status(404).json();      // This runs.
      }
      res.status(200).json(company); // This runs as well.
    });
}

コールバックが添付されたこのルートは、データベースで会社を見つけます。存在しない会社のクエリを実行するelse ifと、ブランチの内部に入り、404応答を送信します。その後、応答も送信する次のステートメントに進みます。これで2つの応答が送信され、エラーメッセージが表示されます。このコードを修正するには、1つの応答のみを送信するようにします。

.exec((err, company) => {
  if (err) {
    res.status(500).json(err);
  } else if (!company) {
    res.status(404).json();         // Only this runs.
  } else {
    res.status(200).json(company);
  }
});

または、応答が送信されたときに戻ることによって:

.exec((err, company) => {
  if (err) {
    return res.status(500).json(err);
  } else if (!company) {
    return res.status(404).json();  // Only this runs.
  }
  return res.status(200).json(company);
});

大きな罪人は非同期関数です。たとえば、この質問から関数を取り上げます。

article.save(function(err, doc1) {
  if (err) {
    res.send(err);
  } else {
    User.findOneAndUpdate({ _id: req.user._id }, { $push: { article: doc._id } })
    .exec(function(err, doc2) {
      if (err) res.send(err);
      else     res.json(doc2);  // Will be called second.
    })

    res.json(doc1);             // Will be called first.
  }
});

ここではfindOneAndUpdate()、コードサンプルに非同期関数()があります。エラーがない場合(errfindOneAndUpdate()が呼び出されます。この関数は非同期なので、res.json(doc1)すぐに呼び出されます。にエラーがないと仮定しfindOneAndUpdate()ます。次にres.json(doc2)in elseが呼び出されます。これで2つの応答が送信され、ヘッダーを設定できませんというエラーメッセージが表示されます。

この場合の修正は、を削除することres.json(doc1)です。両方のドキュメントをクライアントに送り返すにはres.json()、elseをと書くことができますres.json({ article: doc1, user: doc2 })


2
あなたは非同期関数の内部にある、としなければならないreturnres.json
Genovo

私の問題はres.sendforループの使用でした。
Maihan Nijat

1
これは最後に問題を理解して修正するのに役立ちました、ありがとう:)
Pankaj Parkar 2018年

私の時間を節約してくれてありがとう
Mohammad Faisal

これは間違いなく最良の答えです!
Juanma Menendez

53

私はこれと同じ問題を抱えていて、それが私がステートメントres.redirectなしで呼び出していたためであることがわかったreturnので、next関数も直後に呼び出されていました:

auth.annonymousOnly = function(req, res, next) {
    if (req.user) res.redirect('/');
    next();
};

どちらであるべきか:

auth.annonymousOnly = function(req, res, next) {
    if (req.user) return res.redirect('/');
    next();
};

43

多くの人がこのエラーに遭遇しました。これを非同期処理と混同しています。ほとんどの場合、コードの一部は最初のティックでヘッダーを設定しており、その後のティックで非同期コールバックを実行しています。その間に応答ヘッダーが送信されますが、さらにヘッダー(30Xリダイレクトなど)が追加のヘッダーを追加しようとしますが、応答ヘッダーが既に送信されているため、遅すぎます。

エラーの原因は正確にはわかりませんが、調査する可能性のある領域としてコールバックを確認してください。

コードを簡略化するための簡単なヒント。取り除くapp.configure()とだけ呼んでapp.use、あなたのトップレベルの範囲内で直接。

Facebookおよび他のサードパーティの認証プロバイダーを実行するeveryauthモジュールも参照してください。


30XリダイレクトはHTTP応答コードです。 w3.org/Protocols/rfc2616/rfc2616-sec10.html コード300〜399はリダイレクトのさまざまなバリエーションであり、クライアントを代替URLに送信するために302および301が一般的に使用されます。ノードでresponse.redirect(...)を実行すると、30Xリダイレクトヘッダーが応答で送信されます。
Peter Lyons、2011

3
ああ。30回のリダイレクトか何かを想像していた
Janac Meena

17

私はこの問題に頭を悩ませましたが、コールバックの処理に関する不注意な間違いが原因で発生しました。返されないコールバックにより、応答が2回設定されます。

私のプログラムには、リクエストを検証してDBをクエリするコードがありました。エラーがあるかどうかを検証した後、検証エラーでindex.jsをコールバックしていました。そして、検証に合格すると、それが進み、成功/失敗でデータベースにヒットします。

    var error = validateRequestDetails("create",queryReq);
    if (error)
        callback(error, null);
   else
    some code 
    callback(null, success);

何が起こっていたか:検証が失敗した場合、コールバックが呼び出され、応答が設定されます。しかし返されませんでした。したがって、引き続きメソッドはdbに移動し、成功/失敗をヒットします。同じコールバックを再度呼び出して、応答が2回設定されるようにします。

したがって、解決策は簡単です。エラーが発生してメソッドが実行を継続しないように、コールバックを「返す」必要があるため、応答オブジェクトを1回設定します。

  var error = validateRequestDetails("create",queryReq);
    if (error)
        callback(error, null);
        return;
    else
       some code 
       callback(null, success);

1
ありがとう!これも私の問題でした。ちょうどctrl + f callback(...)を実行して、return;後でres.send(...)2回呼び出される原因となっていたアフターアフターがないことを見つけました。

15

このタイプのエラーは、応答の送信後にステートメントを渡すときに発生します。

例えば:

res.send("something response");
console.log("jhgfjhgsdhgfsdf");
console.log("sdgsdfhdgfdhgsdf");
res.send("sopmething response");

応答が送信されると、以下res.sendは実行されないため、表示されているエラーが発生します。

何かしたい場合は、応答を送信する前に行う必要があります。


これは私の正確な問題でした:)
Joel Balmer

6

res.endまたはres.sendの後にnext()関数を呼び出そうとすると、このエラーが発生することがあります。関数でres.sendまたはres.endの後にnext()がある場合は、削除してみてください。注:ここでnext()は、クライアントに応答(つまりres.sendまたはres.end)で応答した後)でも、コードを実行して再度応答しようとしているため。

例:

router.get('/',function (req,res,next){
     res.send("request received");
     next(); // this will give you the above exception 
});

next()上記の関数から削除すると機能します。


6

コールバック関数を使用している場合はreturnerrブロックの後に使用します。これは、このエラーが発生する可能性があるシナリオの1つです。

userModel.createUser(data, function(err, data) {
    if(err) {
      res.status = 422
      res.json(err)
      return // without this return the error can happen.
    }
    return res.json(data)
  })

Nodeバージョンでテストされv10.16.0、Express4.16.4


4

このエラーは、2つの応答を送信したときに発生します。例えば ​​:

if(condition A)
{ 

      res.render('Profile', {client:client_});

}

if (condition B){

      res.render('Profile', {client:client_});
    }
  }

なんらかの理由で条件AとBが真であると想像してみrenderてください。


3

私の場合、問題を引き起こしていたのは304応答(キャッシュ)でした。

最も簡単な解決策:

app.disable('etag');

より詳細な制御が必要な場合の代替ソリューション:

http://vlasenko.org/2011/10/12/expressconnect-static-set-last-modified-to-now-to-avoid-304-not-modified/


私の場合も304応答。加工にはファイバーを使用しています。とにかくあなたの答えが大いに役立つ。ありがとう
ディリープスタンリー2014

誰もがetagヘッダーを削除することの意味を説明できますか?
mattwilsn 2016年

2
ETagを使用すると、サーバーは変更されていないコンテンツを送信できなくなります。オフにすると、この機能が無効になります。ETagウィキペディアエントリ(en.wikipedia.org/wiki/HTTP_ETag)には、より長い説明があります。
2016年

3

私の場合componentWillUnmount、Reactコンポーネントのコールバックでチャンネルの登録を解除しなかったときに、Reactとpostal.jsでこれが発生しました。


2

これに来て誰も助けてくれず、他の解決策のどれも役に立たなかった場合、私の場合、これは画像のアップロードを処理したがタイムアウトを処理しなかったルートに現れたため、アップロードに時間がかかりすぎてタイムアウトした場合、コールバックが発生したタイムアウト応答が送信された後、 res.send()を呼び出すと、タイムアウトが考慮されるようにヘッダーがすでに設定されているため、クラッシュが発生しました。

これは、非常に短いタイムアウトを設定し、かなり大きな画像でルートをたどることによって簡単に再現され、クラッシュは毎回再現されました。


1
これを回避するためにタイムアウトをどのように処理しましたか?

2

これを傾けただけです。この関数を介して応答を渡すことができます。

app.use(function(req,res,next){
  var _send = res.send;
  var sent = false;
  res.send = function(data){
    if(sent) return;
    _send.bind(res)(data);
    sent = true;
};
  next();
});

2

このミドルウェアを追加すると動作します

app.use(function(req,res,next){
 var _send = res.send;
var sent = false;
res.send = function(data){
    if(sent) return;
    _send.bind(res)(data);
    sent = true;
};
next();
});

2

これは、応答がクライアントに配信され、再び応答を試みているときに発生します。このエラーの原因となるどこかでクライアントに再び応答を返していることをコードにチェックインする必要があります。返却したい場合は一度チェックして返却してください。


1

私が約束を入れ子にしているときに私はこの問題を抱えていました。promise内のpromiseはサーバーに200を返しますが、外側のpromiseのcatchステートメントは500を返します。これを修正すると、問題はなくなりました。


これをどのように正確に修正しましたか?約束についても同じ問題があります。それらをネストすることは避けられません... returnステートメントで実行を停止するにはどうすればよいですか?
saurabh

1

ここにnuxtから来ましたが、問題はコンポーネントのasyncDataメソッドにreturnありました。データをフェッチしてそこにヘッダーを設定することを約束するのを忘れていました。


1

コードが単一のリクエストに対して複数のres.send()ステートメントを返すかどうかを確認してください。この問題があったときのように...

この問題は、Resifyノードアプリケーションで発生しました。間違いは

switch (status) { case -1: res.send(400); case 0: res.send(200); default: res.send(500); }

ブレークを書かずにスイッチを使っていろいろなケースを扱っていました。スイッチケースにあまり慣れていない人は、休憩なしでキーワードを返すことを知っています。大文字と小文字のコードとその次の行は、何があっても実行されます。したがって、1つのres.sendを送信したいのに、この間違いのために複数のres.sendステートメントが返され、

エラーは、クライアントに送信された後にヘッダーを設定できません。これを追加するか、return res.send(200)のような各res.send()メソッドの前にreturnを使用して解決しました

switch (status) { case -1: res.send(400); break; case 0: res.send(200); break; default: res.send(500); break; }


同じことが私にも起こりました。else ifコンディションでも解決しました。
Amr AbdelRahman

1

これはノードのことである可能性が非常に高く、99%が2回のコールバックで2回応答したり、next()が2回応答したりするなど、間違いありません。ループ内でnext()を使用することで問題が解決しました。ループからnext()を削除するか、それを複数回呼び出すのを停止します。




1

マングースに起因する同じ問題がありました。

を有効Promisesにする必要があることを修正するmongoose.Promise = global.Promiseには、コードに:を追加して、の使用を有効にしnative js promisesます。

この解決策の他の選択肢は次のとおりです。

var mongoose = require('mongoose');
// set Promise provider to bluebird
mongoose.Promise = require('bluebird');

そして

// q
mongoose.Promise = require('q').Promise;

ただし、最初にこれらのパッケージをインストールする必要があります。


1

RNDの後でエラーが見つかりました:

1)私のエラーコード:

return res.sendStatus(200).json({ data: result });

2)私の成功コード

return res.status(200).json({ data: result });

違いは、私が使用していることであるsendStatusを()の代わりに、状態()


0

Typescriptでの問題は、メッセージを受信した後、websocket接続を閉じなかったことです。

WebSocket.on("message", (data) => {
    receivedMessage = true;
    doSomething(data);
    localSocket.close(); //This close the connection, allowing 
});

0

上からの助けが得られない場合:noobsこのエラーの背後にある理由は、リクエストを複数回送信することです。

module.exports = (req,res,next)=>{
        try{
           const decoded  = jwt.verify(req.body.token,"secret");
           req.userData = decoded;
           next();
        }catch(error){
            return res.status(401).json({message:'Auth failed'});
        }
        next();   
        }

`上記でnext()を2回呼び出すとエラーが発生します

  1. router.delete('/:orderId', (req, res, next) => { Order.remove({_id:req.params.orderId},(err,data)=>{ if(err){ **res.status(500).json(err);** }else{ res.status(200).json(data); } *res.status(200).json(data);* }) })

ここで応答は2回送信されますあなたがすでに応答を送信したかどうかを確認してください


0

私の場合、複数のコールバックが原因で発生します。next()コード中にメソッドを複数回呼び出しました


0

私の問題は、メソッドがの中にsetIntervalあるif/elseブロックが実行されていたclearIntervalことelseです:

      const dataExistsInterval = setInterval(async () => {
        const dataExists = Object.keys(req.body).length !== 0;
        if (dataExists) {
          if (!req.files.length) {
            return res.json({ msg: false });
          } else {
              clearInterval(dataExistsInterval);
            try {
            . . .

clearInterval前に置くif/elseことはトリックをしました。



-1

このエラーが発生した場合に私がしなければならなかったのは、res.end()だけでした。

 auth.annonymousOnly = function(req, res, next) {
 // add other task here   
   res.end();    
  };

直面する可能性のあるもう1つの問題は、res.jsonとresの後にコードがあることです。書く。この場合、その後で実行を停止するにはreturnを使用する必要があります。

 auth.annonymousOnly = function(req, res, next) {

  if(!req.body.name)
  {
    res.json({error:"some error"});
    return;
  }
  let comp = "value"; // this is the code after res.json which may cause some problems so you have to use return 
};
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.