【问题标题】:Can't set headers after they are sent. Nodejs/express with axios发送后无法设置标题。 Nodejs/express 与 axios
【发布时间】:2018-01-22 19:23:08
【问题描述】:

我已经看到了这个错误,更多的只是想知道如何解决它。我需要能够将数据输出为 json 对象。有没有办法解决这个问题。

我基本上是从教程中复制和粘贴,不知道为什么我在这里得到它,除了深度请求调用可能?

这是错误:

Error: Can't set headers after they are sent.
[0]     at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:344:11)
[0]     at ServerResponse.header (C:\Users\Amazo\Thrifa\moovr\node_modules\keystone\node_modules\express\lib\response.js:730:10)
[0]     at ServerResponse.send (C:\Users\Amazo\Thrifa\moovr\node_modules\keystone\node_modules\express\lib\response.js:170:12)
[0]     at ServerResponse.json (C:\Users\Amazo\Thrifa\moovr\node_modules\keystone\node_modules\express\lib\response.js:256:15)
[0]     at C:/Users/Amazo/Thrifa/moovr/src/server/API/routes/offers.js:28:21
[0]     at Promise.<anonymous> (C:/Users/Amazo/Thrifa/moovr/src/server/API/controllers/store/OfferController.js:25:7)
[0]     at Promise.<anonymous> (C:\Users\Amazo\Thrifa\moovr\node_modules\keystone\node_modules\mongoose\node_modules\mpromise\lib\promise.js:177:8)
[0]     at emitOne (events.js:77:13)
[0]     at Promise.emit (events.js:169:7)
[0]     at Promise.emit (C:\Users\Amazo\Thrifa\moovr\node_modules\keystone\node_modules\mongoose\node_modules\mpromise\lib\promise.js:84:38)
[0]     at Promise.fulfill (C:\Users\Amazo\Thrifa\moovr\node_modules\keystone\node_modules\mongoose\node_modules\mpromise\lib\promise.js:97:20)
[0]     at C:\Users\Amazo\Thrifa\moovr\node_modules\keystone\node_modules\mongoose\lib\query.js:1406:13
[0]     at model.Document.init (C:\Users\Amazo\Thrifa\moovr\node_modules\keystone\node_modules\mongoose\lib\document.js:254:11)
[0]     at completeOne (C:\Users\Amazo\Thrifa\moovr\node_modules\keystone\node_modules\mongoose\lib\query.js:1404:10)
[0]     at Immediate.cb (C:\Users\Amazo\Thrifa\moovr\node_modules\keystone\node_modules\mongoose\lib\query.js:1158:11)
[0]     at Immediate._onImmediate (C:\Users\Amazo\Thrifa\moovr\node_modules\keystone\node_modules\mongoose\node_modules\mquery\lib\utils.js:137:16)
[0]     at processImmediate [as _immediateCallback] (timers.js:383:17)

代码如下:

import OfferController from '../controllers/store/OfferController';
import RequestManager from '../utils/RequestManager';
import axios from 'axios';

const offerRoutes = (app) => {
  app.get('/API/offers', (req, res, next) => {
    axios
      .get(
        'https://d2fzm6xoa70bg8.cloudfront.net/login?auth=e4031de36f45af2172fa8d0f054efcdd8d4dfd62',
      )
      .then((response) => {
        axios
          .get('https://d2fzm6xoa70bg8.cloudfront.net/offerfilter?', {
            headers: { Token: response.data.token },
          })
          .then((response) => {
            const { data } = response;

            data.map((item, i) => {
              OfferController.findOne({ offer: item.offer }, (err, result) => {
                if (err) {
                  res.json({
                    message: err,
                  });

                  return;
                }
                res.json({
                  message: 'Offer already exist',
                  result,
                });
              });

              const params = {
                offer: item.offer,
                cert: item.cert,
                txid: item.txid,
                expires_in: item.expires_in,
                expires_on: item.expires_on,
                expired: item.expired,
                height: item.height,
                time: item.time,
                category: item.category,
                title: item.title,
                quantity: item.quantity,
                currency: item.currency,
                sysprice: item.sysprice,
                price: item.price,
                ismine: item.ismine,
                commission: item.commission,
                offerlink: item.offerlink,
                offerlink_guid: item.offerlink_guid,
                offerlink_seller: item.offerlink_seller,
                private: item.private,
                safesearch: item.safesearch,
                safetylevel: item.safetylevel,
                paymentoptions: item.paymentoptions,
                paymentoptions_display: item.paymentoptions_display,
                alias_peg: item.alias_peg,
                description: item.description,
                alias: item.description,
                address: item.address,
                alias_rating: item.alias_rating,
                alias_rating_count: item.alias_rating_count,
                alias_rating_display: item.alias_rating_display,
                geolocation: item.geolocation,
                offers_sold: item.offers_sold,
              };
              OfferController.create(params, (err, results) => {
                if (err) {
                  console.log(err);

                  return;
                }

                res.write(results);
              });
            });
          })
          .catch((err) => {
            console.log('err 2nd request', err);
            res.json({
              confirmation: 'fail after 2nd request',
              message: err,
            });
          });
      })
      .catch((err) => {
        console.log('err 1st request');
        res.json({
          confirmation: 'fail before 2nd request',
          message: err,
        });
      });
  });
};
export default offerRoutes;

【问题讨论】:

    标签: json node.js express axios


    【解决方案1】:

    您的res.json(...) 包含在对map 的调用中,这意味着您将对res.json 进行多次调用,从而导致为同一个res 实例多次设置Content-Type 标头。

    【讨论】:

    • 我应该如何返回从 create 方法获得的数据?是否有最佳实践来解决这个问题?
    • 目前您正在(尝试)从您的 findOne 和您的 create 方法返回数据。你想退回哪一个?如果您解释此路由处理程序的用途,将会有所帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-03
    • 1970-01-01
    • 2018-02-21
    • 1970-01-01
    • 2014-09-08
    相关资源
    最近更新 更多