2017-11-21 20 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 히트하기 전에 수행되도록 제대로 헤더를 변경하는 방법을 알아낼 수 없습니다. 그것은 자바 스크립트의 비동기 성질에 기인 할 가능성이 높습니다. 아직 제대로 이해하지 못했지만, res.endHead가 res.send 전에 호출되도록하려면 어떻게해야합니까?

고맙습니다. 미리 살펴 주셔서 감사합니다.

+0

가능한 복제 [어떻게 express.js 자산에 대한 응답 헤더를 설정할 수 있습니다 (https://stackoverflow.com/questions/23751914/how-can-i-set-response-header-on-express -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.send보다 res.writeHead가 먼저 호출되도록하려면 어떻게해야합니까?

당신은 당신의 응답 개체의 헤더 값을 설정 res.setHeader()로 변경하여 res.writeHead() 전화를 res.send()을 사용하려고하는 경우. 또한 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는 스텔스 downvoting을 사랑해. – David