【问题标题】:Error:Can't set headers after they are sent in express错误:快递发送后无法设置标题
【发布时间】:2017-01-18 20:49:29
【问题描述】:

我正在探索 node 并使用 redux 表达,我想在页面呈现后设置一个 cookie,并想使用更新的状态来设置一个我收到此错误的 cookie。

请帮助我获得以下答案? 1)让我知道我写的语法是否正确,如果不正确,那么应该怎么做? 2) 成功渲染 ejs 文件后如何设置 cookie 响应?

router.get('/dashboard',isLoggedIn,(req, res) => {


    store.dispatch(initialize(reduxOauthConfig))
        .then(() => match({ routes: dashroutes, location: req.url }, (error, redirectLocation, renderProps) => {
          if (redirectLocation) {
            res.redirect(301, redirectLocation.pathname + redirectLocation.search);
          } else if (error) {
            res.status(500).send(error.message);
          } else if (!renderProps) {
            res.status(404).send('Not found');
          } else {
            loadOnServer({ ...renderProps, store })
              .then(() => {
                const componentHTML = ReactDOMServer.renderToString(
                  <Provider store={store}>
                    <ReduxAsyncConnect {...renderProps}/>
                  </Provider>
                );

       const initialState = store.getState();


          res.render('dashboard.ejs', {
                    markup: componentHTML,
        intialState:initialState
                 });
             })
         .then(html => {
           // !!! IMPORTANT TO PERSIST SESSION IF JavaScript failed to load / initialize
           res.cookie('authHeaders', JSON.stringify(getHeaders(store.getState())), { maxAge: now() * 0.001 + 14 * 24 * 3600 });

           res.end(html);
       })
         .catch(err => {
           console.log(err.stack);
           res.end(err.message);
         });
   }
 }));
});

【问题讨论】:

  • @JohnWeisz - 我不会称这是一个重复。这里的问题是为什么此特定代码会生成该错误消息以及此代码的违规部分是什么。其他答案没有解决有关此特定代码有什么问题的任何问题。
  • @jfriend00 -- 虽然我同意你的观点,但我也相信在这种情况下这归结为品味和个人喜好问题,考虑到这是服务器端编程的经典问题,其中了解问题背后的一般原则本身就是答案:在标题之前不写入内容,或使用输出缓冲

标签: node.js reactjs express redux


【解决方案1】:

此错误是由于在响应已发送并最终确定后尝试发送更多响应而导致的。这个问题通常是由请求处理程序中的错误异步处理在人们的代码中触发的。

在你的承诺链中,你正在做res.render(),然后是res.cookie(),然后是res.end(html)

res.render() all 自己发送响应。然后,以下两个命令会在已发送响应时尝试发送响应,因此您会收到您所看到的错误。

此外,loadOnServer() 之后的第二个 .then() 处理程序似乎期待您命名为 html 的参数,但前一个 .then() 处理程序没有返回任何内容,因此 html 参数将未定义。

我不清楚你打算在这里使用什么逻辑,因为你似乎试图在同一个承诺链中发送两次渲染的 HTML。

【讨论】:

  • 渲染仪表板后,redux 通过调用 UPDATE_HEADER 操作更新了我的标题状态,我想将这些更新的标题设置为 cookie。另外,html 元素只不过是 componentHTML。
  • 请告诉我如何在 res.render 之后设置 cookie 或了解有关问题的更深入信息,检查 link 并检查显示在 auth 部分下的小部件中的服务器状态和标头部分跨度>
  • @Coder - 发送响应后不能设置 cookie。您需要先设置它。 cookie 是响应的一部分。您可以在移动res.render() 之前移动res.cookie() 并删除res.end(html)。如果您依赖res.render() 的某些副作用,这就是为什么您要在发送呈现的 HTML 后设置 cookie,那么您必须修复设计。你根本做不到。您可以手动渲染到变量中(不会发送结果),然后设置 cookie,然后发送 html。但实际上,您应该删除副作用设计。
  • 好的。谢谢你的信息。我正在制作一个 renderHTML 函数并调用我的组件而不是 res.render 在那里渲染。然后将设置一个 cookie。
  • @Coder - 听起来像是一个更好的设计。
猜你喜欢
  • 2017-01-18
  • 2015-02-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-13
  • 2015-03-07
相关资源
最近更新 更多