【问题标题】:How to upload multiple files with additional info inside object如何在对象内上传带有附加信息的多个文件
【发布时间】:2021-12-03 05:26:29
【问题描述】:

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

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

【问题讨论】:

  • 你不应该附加对象,只是字符串或文件。分别附加文件和附加信息。见这里:developer.mozilla.org/en-US/docs/Web/API/FormData/append
  • @ADyson 服务器将文件视为数组,当我使用 files 语法发送没有其他道具的文件时。 - formData.append('files', files[i]);

标签: javascript file-upload axios form-data


【解决方案1】:

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

第二个参数 - value - 它说:

字段的值。这可以是 USVString 或 Blob(包括 子类,例如 File)。如果这些都没有指定,则值为 转换为字符串。

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

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

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

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

例如,这样的事情应该会更好:

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

【讨论】:

  • 我知道我可以将其他道具作为单独的道具发送,但这不是我要实现的目标。例如,如果我上传多张图片,我想选择其中一些图片并说该图片是主要的。
  • 嗯,你需要想办法向服务器表示这个事实,但是你必须通过一个单独的属性来做到这一点 - 例如也许您可以.append("mainImage", "filenameOfMainImage").append("mainImageIndex", 0) 或其他东西 - 只是一些信息告诉服务器阵列中的哪些图像是“主要”图像。发挥你的想象力。
  • 但是,我已经回答了为什么你会得到你看到的输出的具体问题 - 这是因为你提供给 .append() 方法的内容不受支持。您必须value 属性仅提供字符串或Blob。我还解释了一种支持的可能替代方法,并为您提供了针对您的特定用例的其他替代方法的想法。所以我认为这个问题已经解决了。您决定的确切数据结构实际上取决于您,但我已经解释了您可以做什么和不允许做什么。
  • 谢谢,我会发送与其他道具分开的文件。
猜你喜欢
  • 2019-10-14
  • 1970-01-01
  • 2015-05-26
  • 2023-03-11
  • 2020-07-09
  • 2020-03-15
  • 2021-12-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多