2015-03-05 2 views
3

Я новичок в nodeJS и асинхронном программировании. Я использую экспресс в качестве базы для своего приложения, есть действительно только один маршрут, который обслуживает страницу и принимает загрузку из формы. Я хочу сделать запрос POST для внешней службы после того, как файл был загружен. Попытка выполнить любой код после res.send (200) приводит к сообщению об ошибке Error: Can't set headers after they are sent.Функция ExpressJS 4 после res.send()

Я использую пакет request, чтобы отправить сообщение внешней службе.

var express = require('express'); 
var router = express.Router(); 
var util = require("util"); 
var request = require("request"); 

/* POST uploads. */ 
router.post('/', function(req, res, next) { 
    console.log("LOG:" + util.inspect(req.files)); 
    res.send('respond with a resource'); 
    postFile(req.files.file.path); 
}); 

var postFile = function(path) { 
    var opts = { 
     method: 'POST', 
     uri: 'https://example.com/api/files.upload', 
     formData: { 
      token: "xxx", 
      file: fs.createReadStream(req.files.file.path) 
     } 
    } 

    // console.log("LOG:\n" + util.inspect(opts)); 

    request.post(opts, function(error, response, body) { 
     if (error) { 
      console.log("ERROR LOG: " + util.inspect(error)); 
     } else { 
      console.log("RESPONSE LOG:" + util.inspect(response)); 
     } 
    }); 
} 

module.exports = router; 

Функция postFile отлично работает на своем собственном и даже добавление console.log непосредственно после получения результатов res.send в одной и той же ошибки. Как я могу продолжать выполнять код на сервере после отправки ответа клиенту?

журнала Выход из узла:

POST /uploads 200 85.201 ms - 23 Error: Can't set headers after they are sent. at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:335:11) at ServerResponse.header (/Users/jason/dev/test/file-share/node_modules/express/lib/response.js:700:10) at ServerResponse.send (/Users/jason/dev/test/file-share/node_modules/express/lib/response.js:154:12) at fn (/Users/jason/dev/test/file-share/node_modules/express/lib/response.js:934:10) at View.exports.renderFile [as engine] (/Users/jason/dev/test/file-share/node_modules/jade/lib/index.js:374:12) at View.render (/Users/jason/dev/test/file-share/node_modules/express/lib/view.js:93:8) at EventEmitter.app.render (/Users/jason/dev/test/file-share/node_modules/express/lib/application.js:566:10) at ServerResponse.res.render (/Users/jason/dev/test/file-share/node_modules/express/lib/response.js:938:7) at /Users/jason/dev/test/file-share/app.js:58:7 at Layer.handle_error (/Users/jason/dev/test/file-share/node_modules/express/lib/router/layer.js:58:5)

+0

Одна ошибка программирования заключается в том, что 'postFile()' должен использовать переданный ему аргумент 'path', а не' req.files.file.path'. Наверное, не причина вашей проблемы. – jfriend00

+0

Если вы посмотрите на трассировку стека, это от 'handle_error', что означает, что выражение поймало ошибку и попыталось отправить ответ об ошибке. Указанная ошибка 'req.files.file.path' @ jfriend00, вероятно, вызывает функцию throw, поэтому ваш' res.send' отправляет и закрывает соединение, а затем синтаксическая ошибка пытается отправить страницу с ошибкой. Прокомментируйте 'res.send', и вы увидите фактическую ошибку. – loganfsmyth

ответ

1

Там нет ничего плохого в коде ниже, вы можете выполнить код после ответа на запрос. Вы просто не можете отправить заголовки снова.

router.post('/', function(req, res, next) { 
    console.log("LOG:" + util.inspect(req.files)); 
    res.send('respond with a resource'); 
    postFile(req.files.file.path); 
}); 

Использование request для POST или GET-то не будет отвечать на Ваш запрос, если вы не хотите.

+0

Я тоже так думаю, но факт остается фактом: даже при использовании console.log после res.send возвращает ту же ошибку. Возможно, я как-то неправильно настроил свой проект. –

+0

Возможно, это сообщение об ошибке поступает из другой части вашего кода. – prbc

+0

Он ничего не делает. Он принимает файл и пытается его загрузить. удаление postFile (req.files.file.path); после res.send() и код работает нормально, добавьте console.log ('test'); после res.send() и появляется такое же сообщение об ошибке. –

0

postFile() Ваша функция имеет в виду req.files.file.path в этой строке:

file: fs.createReadStream(req.files.file.path) 

но req объект не передается к нему. Это должно вызвать какое-то исключение.

Похоже, вы должны использовать только:

file: fs.createReadStream(path) 

поскольку вы передаете путь к postFile(path).

+0

Спасибо, что указала, что я была взволнована на мгновение, когда я подумал, что это может быть просто проклятая ошибка. Однако его изменение не меняет ответ. Полное удаление вызова и его замена простым консолью.log не изменяет ответ. –

Смежные вопросы