使用 express / request-promise 的条件重定向

Conditional redirect with express / request-promise

我对 expressrequest-promise 模块比较陌生, 并且需要创建一个 service SserverA 调用 在 SServerB 询问一些额外信息后, 它重定向 serverAServerC 的请求。 自从我得到一个 错误:发送后无法设置 headers。 尽管我自己没有添加任何东西,但我想知道有人可以帮助我直接完成这个工作流程。

这是代码: `

const express = require('express')
const rp = require('request-promise')
  ...

app.get('/dispatch', cors(), (req, res, next) => {

var options = {
   uri: 'https://ServerB/calc-something..',
   headers: {
      'User-Agent': 'its-me',
      'Data': data_from_serverA
   },
   resolveWithFullResponse: true, // Get statuscode
   json: true // Parse the JSON string in the response
};

rp(options) // Do request to serverB
    .then(function (response) {
       console.log(`ServerB responded with statuscode ${response.statusCode}`)
       // No error, so redirect original res 
       res.redirect('https://serverC/...') // error occurs here
       return next(response)
    })
    .catch(function (err) { 
        console.log(`ServerB responded with error ${err}`)
        return next(err) // send 500 to serverA
    })
})

`

您的 cors() 中间件正在设置 CORS headers。这导致 headers 在您的承诺正在解决时被发送。

重定向也会发送 headers,这就是问题所在。重定向设置了 location header,但您已经发送了 header,因此不会起作用。

解决方案是将最终的中间件一分为二。首先,检查是否需要重定向,如果需要,则执行此操作。否则,在 req object 上设置你需要的任何数据,并在 cors 调用后处理它。

您的最终路线将类似于:

app.get('/dispatch', checkRedirect, cors(), (req, res, next) => { //do something useful, or send your error })

checkRedirect 函数的内容与上面的内容非常相似。但是,您不会将数据传递给 next() 函数。这只是将控制权传递给下一个中间件。相反,将您需要的任何数据放在 req object 上,并在最终的中间件中处理它,在 cors 之后。如果您所做的只是设置 500 错误,那么您甚至不需要 CORS。

根据@Rampant 的回答, 这就是我用 request-promise (rp):

做的
function checkPrecondition(req, res, next){
    req.precondition = false
    rp({ method: 'POST',
       ...
    })
    .then((data) => {
       ...
       req.precondition = true
       next()
    })
    .catch((data) => {
       ...
       next()
    })
}

并在 express 处理程序中:

app.post('/query', checkPrecondition, cors(), (req, res, next) => {
      if(!req.precondition){
          res.status(400).send(JSON.stringify({status: 'insufficient'}))
          return
      }
      res.redirect('target.host')
})

感谢您解决 CORS 问题。