#javascript #file-upload #axios #form-data
Вопрос:
Я пытаюсь загрузить несколько файлов, используя FormData
в качестве массива объекты, содержащие файл и другие необходимые свойства, но я не получаю ожидаемых результатов.
import api from './api';
const formData = new FormData();
// File input with multiple attribute
const files = this.$refs.photo.files;
if (files.length > 0) {
for (let i = 0; i < files.length; i ) {
formData.append('files', { file: files[i], someOtherProp: 'value' });
}
}
api.createArticle(formData);
// api/index.js
import axios from 'axios';
import config from '@/config';
const api = axios.create({
baseURL: config.api,
timeout: config.apiTimeout,
});
createArticle(payload) {
return api.post('/articles', payload, {
headers: {
'Content-Type': 'multipart/form-data',
}
});
}
export {
createArticle
};
Когда я отправляю запрос, это то, что я получаю
Комментарии:
1. Вы не должны добавлять объекты, только строки или файлы. Добавьте файлы и дополнительную информацию отдельно. Смотрите здесь: developer.mozilla.org/en-US/docs/Web/API/FormData/append
2. Сервер @ADyson видит файлы как массив, когда я отправляю только файл без других реквизитов, используя
files
синтаксис. —formData.append('files', files[i]);
Ответ №1:
Документация функции добавления FormData показывает, что она принимает два или три параметра (3-й является необязательным).
О втором параметре — value
— в нем говорится:
Значение поля. Это может быть строка USV или большой двоичный объект (включая подклассы, такие как файл). Если ни один из них не указан, значение преобразуется в строку.
Ваш код пытается передать объект для этого параметра, а не строку или большой двоичный объект. Поэтому FormData делает именно то, что указано в документации, и преобразует этот объект в строку. [Object object]
это то, что JavaScript всегда выводит по умолчанию, если вы пытаетесь напрямую структурировать объект.
Если вы хотите добавить имя файла специально, как вы можете видеть из документации, дополнительный 3-й параметр filename
предоставляется специально для этой цели.
Однако, если вы хотите передать какое-либо другое связанное свойство, вам нужно будет сделать это в отдельном поле в FormData.
Также не следует повторно добавлять элементы данных с одним и тем же именем — ваш сервер может видеть только последний. Чтобы это работало наиболее надежным способом , вы должны использовать синтаксис массива, например formData.append("files[]"...
, чтобы сервер видел массив данных с этим именем, а не один элемент. Вы можете сделать то же самое для этих дополнительных свойств, которые вы хотите передать, затем вы также можете передать несколько элементов, и их номер индекса будет совпадать с номером индекса файла, с которым они связаны, когда ваш сервер получит опубликованные данные.
Например, что-то вроде этого должно работать лучше:
for (let i = 0; i < files.length; i ) {
formData.append('files[]', files[i]);
formData.append('someOtherProp[]', 'value');
}
Комментарии:
1. Я знаю, что могу отправить другую опору в качестве отдельной опоры, но это не то, чего я собираюсь достичь. Например, если я загружаю несколько изображений, я хочу выбрать некоторые из этих изображений и сказать, что это изображение является основным.
2. Ну, вам нужно придумать какой — то способ представления этого факта серверу, но вы должны сделать это с помощью отдельного свойства — например, возможно, вы можете
.append("mainImage", "filenameOfMainImage")
.append("mainImageIndex", 0)
или что-то в этом роде-просто некоторая информация, чтобы сообщить серверу, какое из изображений в массиве является «основным». Используй свое воображение.3. Тем не менее, я ответил на конкретный вопрос о том, почему вы получаете результат, который вы видели, — это потому, что то, что вы предоставили
.append()
методу, не поддерживается. Для свойства необходимо указать только строку или большой двоичныйvalue
объект. Я также объяснил возможный альтернативный подход, который поддерживается, и дал вам идеи для других альтернативных подходов, а также для вашего конкретного случая использования. Поэтому я думаю, что вопрос более чем решен. Точная структура данных, которую вы выберете, действительно зависит от вас, но я объяснил, что вам разрешено, а что нет.4. Спасибо, я отправлю файлы отдельно от других реквизитов.