如何上传包含对象内部附加信息的多个文件

How to upload multiple files with additional info inside object

我正在尝试使用 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
};

当我发送请求时,这就是我得到的

documentation of the FormData append function 表明它接受两个或三个参数(第三个是可选的)。

第二个参数 - value - 它说:

The field's value. This can be a USVString or Blob (including subclasses such as File). If none of these are specified the value is converted to a string.

您的代码试图为此参数传递对象,而不是字符串或 Blob。因此 FormData 完全按照文档所说的那样做,它将在这种情况下执行该操作,并将该对象转换为字符串。如果您尝试直接对对象进行字符串化,[Object object] 是 JavaScript 始终默认输出的内容。

如果您希望专门为文件附加一个名称,正如您从文档中看到的那样,可选的第三个参数 filename 是专门为此目的提供的。

但是,如果您想传递一些其他相关的 属性,则需要在 FormData 的单独字段中进行传递。

此外,您不应重复附加同名数据项 - 您的服务器可能只会看到最后一个。为了以最可靠的方式工作,您应该使用数组语法,例如formData.append("files[]"...,因此服务器应该看到具有该名称的数据数组,而不是单个项目。您可以对要传递的这些附加属性执行相同的操作,然后您还可以传递多个项目,当您的服务器收到 POSTed 数据时,它们的索引号将与它们相关文件的索引号相匹配。

例如,像这样的东西应该效果更好:

for (let i = 0; i < files.length; i++) {
  formData.append('files[]', files[i]);
  formData.append('someOtherProp[]', 'value');
}