Пустые данные формы в POST-запросе

Я делаю простое приложение, которое будет загружать файл на сервер, который был перетащен на холст.

Вот небольшой пример того, как выглядит код перетаскивания:

var files = event.dataTransfer.files;
var formData = new FormData();
formData.append('files', files);

Используя инструменты отладки, я знаю, что files определен правильно.

Затем я делаю запрос:

var xhr = new XMLHttpRequest();
xhr.open('POST', '/upload', true);
xhr.send(formData);

Но мой сервер, на котором работает Node JS, получает пустое тело ответа:

var express = require('express');
var bodyParser = require("body-parser");
app.use(bodyParser.urlencoded({
    extended: false
}));
app.post('/upload', function(req, res) {
    console.log(req.body.files);
    res.end();
});

Я пробовал отлаживать как на стороне клиента, так и на стороне сервера, но не могу понять. Хотя мне кажется странным, что объект formData выглядит так:

FormData {append: function}
    __proto__: FormData

Почему добавленный объект files не отображается?

Любое понимание того, в чем проблема, будет с благодарностью!


person James Taylor    schedule 19.04.2015    source источник
comment
вы также должны передать имя файла для лучшей совместимости с серверной частью...   -  person dandavis    schedule 19.04.2015


Ответы (2)


Попробуйте изменить

var files = event.dataTransfer.files;

to

var files = event.dataTransfer.files[0];

См. https://developer.mozilla.org/en-US/docs/Web/Guide/Using_FormData_Objects ; см. также данные-формы-узла

person guest271314    schedule 19.04.2015
comment
К сожалению, это не сработало. Тело ответа по-прежнему пусто, а formData по-прежнему выглядит как пустой объект. Я мог бы заглянуть в библиотеку Node, которую вы связали. Прямо сейчас я собирался использовать чистое решение Javascript, но, поскольку я использую Express с EJS, это возможно. - person James Taylor; 19.04.2015
comment
Пробовали использовать json, data-uri вместо объекта formData? - person guest271314; 19.04.2015
comment
Я попытался просто передать JSON, и это тоже не сработало: xhr.send(JSON.stringify(files)); - person James Taylor; 19.04.2015
comment
@JamesTaylor См. stackoverflow.com/questions/28207106/pdf -file-upload-ajax-html для одного файла, stackoverflow.com/questions/28856729/ для нескольких файлов, включая event.dataTransfer.files[0] . Пример с одним файлом, возможно, проще читать части, где файл преобразуется в data URI, base64 строку; json включая имя файла, размер файла, тип файла. Можно включить подход js в сообщение выше, если использование jquery по ссылкам не может быть включено при реализации. - person guest271314; 19.04.2015
comment
Спасибо за ссылки. Я использую JS, а не PHP. Я не уверен, будет ли подход таким же или нет, но я изучу его. - person James Taylor; 19.04.2015
comment
@JamesTaylor POST на сервер должен быть json формат данных; может использовать JSON.parse, JSON.stringify для обработки POST, обслуживать ответ? - person guest271314; 19.04.2015

После слишком долгого времени работы над этой проблемой я, наконец, понял это. Проблема была на стороне сервера; мое приложение Express игнорировало текст сообщения, поскольку я явно не установил bodyParser для приема JSON.

Экспресс-настройка для метода POST должна быть:

var express = require('express');
var bodyParser = require("body-parser");
app.use(bodyParser.json()); // Configures bodyParser to accept JSON
app.use(bodyParser.urlencoded({
    extended: false
}));

С примером метода маршрутизации, например:

app.post('/upload', function(req, res) {
    console.log(req.body.files);
    res.end();
});

Также полезно знать, что эту настройку на стороне сервера можно протестировать, запустив что-то вроде этого:

curl -d '{"file":{"name":"sample"}}' -H "Content-Type: application/json" http://localhost:8080/upload
person James Taylor    schedule 19.04.2015
comment
Установка тела в явном формате JSON не будет корректно обрабатывать реальные файлы. Возможно, вы можете использовать body-parser и другое промежуточное ПО для обработки кодирования multipart/form-data, например Multer. - person Futureproof; 13.11.2019