2017-11-21 12 views
0

このトピックに関するオンラインで多量のstackoverflow質問と記事がありますが、特定のアプリケーションに該当するものはありません。node.js/express:送信後にヘッダーを設定することはできません

router.get('/getFile', (req, res) => { 
    console.log("Calling getFile for file " + req.query.serialNumber + ".") 
    var serialNumber = req.query.serialNumber; 
    let request = new sql.Request(conn); 
    request.query('SELECT FileName + \'.\' + FileExtension AS \'File\', FileType, ContentType, SerialNumber, Chart ' + 
     'FROM dbo.ChangeFiles ' + 
     'WHERE SerialNumber = ' + serialNumber) 
     .then(function (recordset) { 
      log("Successfully retrieved file " + recordset[0].SerialNumber + " from database.") 
      res.writeHead(200, { 
       'Content-Type': recordset[0].ContentType, 
       'Content-disposition': 'attachment;filename=' + recordset[0].File 
      }); 
      res.send(Buffer(recordset[0].Chart)); 
     }).catch(function (err) { 
      log(err); 
      res.send("Issue querying database!"); 
     }); 
}); 

ヘッダーを正しく変更してres.sendヒットの前にヘッダーを変更する方法がわかりません。これはjavascriptの非同期性が原因である可能性が高いですが、私はまだ適切に把握していないことがありますが、res.sendの前にres.writeHeadが呼び出されるようにするにはどうすればよいですか?

ありがとうございました。これをご覧いただきありがとうございます。

+0

(https://stackoverflow.com/questions/23751914/how-can-i-set-response-header-on-express [どのように私はexpress.js資産のレスポンスヘッダを設定することができます]の可能性のある重複-js-assets) – Fals

+0

res.sendの代わりにres.endを使用していますか? –

+1

はres.status()とres.send()と一緒にres.setHeader()を使用します。 – zubair1024

答えて

1

res.writeHead()を使用すると、ヘッダーはすぐにリクエスタに送信されます。 Expressファンクションres.send()which also sends over your headersを使用しているので、既に送信されており、ヘッダがすでに送信されているというエラーが表示されます。代わりに、res.end()を使用しても、ヘッダー送信エラーは発生しません。レスポンスを確定し、残っているチャンクをすべて送信するからです。

res.endHeadがres.sendより前に呼び出されるようにするにはどうすればよいですか?

あなたがres.send()を使用するつもりなら、あなたの応答オブジェクトのヘッダー値を設定するres.setHeader()にごres.writeHead()の呼び出しを変更します。さらに、Expressを使用する場合、res.status(<statusCode>)を使用して応答のstatusを設定することができます。

私が気づいたもう一つのことは、Bufferの使用です。成功応答ハンドラのBufferの作成をBuffer()からBuffer.from()に変更し、Buffer()deprecatedであるように変更する必要があります。

router.get('/getFile', (req, res) => { 
    console.log("Calling getFile for file " + req.query.serialNumber + ".") 

    let serialNumber = req.query.serialNumber 
    let request = new sql.Request(conn) 
    let query = 'SELECT FileName + \'.\' + FileExtension AS \'File\', FileType, ContentType, SerialNumber, Chart ' + 
     'FROM dbo.ChangeFiles ' + 
     'WHERE SerialNumber = ' + serialNumber 

    request.query(query) 
     .then(recordset =>{ 
      console.log("Successfully retrieved file " + recordset[0].SerialNumber + " from database.") 

      let {ContentType, Chart File} = recordset[0] 

      // Set Response Status and Headers 
      res.status(200) 
      res.setHeader('Content-Type', ContentType) 
      res.setHeader('Content-Disposition', `attachment;filename=${File}`)    

      return res.send(Buffer.from(Chart)) 
     }).catch(err => { 
      console.log(err); 
      return res.status(500).send("Issue querying database!"); 
     }) 
}) 
+0

なぜdownvote? – peteb

+1

すごくうまくいった。どうもありがとうございます! downvoteについては、誰が知っている。 StackOverflowはステルスのダウンボウリングが大好きです。 – David

関連する問題