обслуживание файлов из файловой системы с помощью node.js, тело ответа возвращается как пустое

Итак, я пытаюсь вернуть файлы пользователю после того, как они были загружены на сервер. Я храню загруженные файлы в каталоге приложения, в каталоге с именем uploads. Вот код, который я использую для обслуживания файлов:

if (req.url.split("/")[1] == "uploads") {
    console.log("requesting file " + virtualToPhysical(req.url));
    var file = fs.readFile(virtualToPhysical(req.url), function (err, data) {
        if (err) {
            throw err;
        } else {
            res.writeHead(200, { 'Content-Type': mime.lookup(req.url) });
            res.end(data, 'binary');
        }
    });
}

virtualToPhysical просто добавляет путь к каталогу в файловой системе к URL-адресу запроса. Если req.url — «/uploads/image1.jpg», virtualToPhysical выдаст «/path/to/application/uploads/image1.jpg». Вызов mime.lookup() исходит из прилагаемой библиотеки, которая выводит правильный тип MIME для файла.

Этот код работает без ошибок. Заголовки ответов выглядят нормально, но тело каждый раз возвращается пустым, независимо от типа или размера файла. Я пробовал другой метод, используя util.pump(), но он дает тот же результат.

*EDIT:* Я искал все вокруг, и это буквально единственный метод, который, как говорят люди, используется для передачи файла через узел. Я в недоумении, в чем может быть моя проблема. Кто-то предложил не использовать флаг «двоичный» при вызове res.end(), но тот же эффект возникает несмотря ни на что.


person Chairmonkey    schedule 13.08.2012    source источник


Ответы (2)


Удалите аргумент 'binary' из вашего вызова res.end(); параметр encoding применим только в том случае, если вы отправляете строку, и в этом случае вы отправляете буфер. Кроме того, 'binary' был удален как тип кодировки в последних версиях node.

person ebohlman    schedule 13.08.2012
comment
Я пробовал это как с двоичным аргументом, так и без него, оба результата дали один и тот же. - person Chairmonkey; 13.08.2012

Я понял, что проблема была не в fs.readFile открытии файла, а в том, как я сохранял файлы при загрузке. Вместо того, чтобы использовать fs.writeFile() при сохранении загрузки из грозного, вам нужно переименовать его из его местоположения в /tmp. Вот пример:

form.parse(req, function (err, fields, files) {
  file_name = escape(files.upload.name);
  fs.rename(files.upload.path, virtualToPhysical("/uploads/" + file_name), function (err) {
    if (err) {
      throw err;
    } else {
      res.writeHead(200, {'Content-Type': 'text/html'});
      res.end(file_name);
    }
  });
});
person Chairmonkey    schedule 13.08.2012