将多个文件对象作为二维文件数组上传到API

问题描述 投票:0回答:1

我正在尝试使用 django 构建一个 API,它支持将文件作为数组的数组上传。我想要实现的一个例子是,

[
    {
        "string": "Some string",
        "files": [
            "<uploaded file object 1>",
            "<uploaded file object 2>"
        ]
    },
    {
        "string": "Some string",
        "files": [
            "<uploaded file object 3>"
        ]
    },
    {
        "string": "Some string",
        "files": []
    }
]

我不想为此使用base64编码的文件,因为文件有时可能很大,所以我不想增加使用base64的开销。

**我如何以最有效的方式实现此 API 调用,以及调用此 API 的最合适的结构是什么,并帮助一些 javascript 前端代码做到这一点。 **

我尝试将其移至 FormData,在那里我可以实现上面的上传,如下所示,但我无法从前端调用 API,它不起作用可能是因为我编写了错误的代码。

strings: ["Some string", "Some string", "Some string"]
files: [["<uploaded file object 1>", "<uploaded file object 2>"], ["<uploaded file object 3>"]]

对于我的后端,我使用 django(rest 框架),如果需要,这里是序列化器的相关部分

class StringSerializer(serializers.Serializer):
    serializers = serializers.ListField(child=serializers.CharField())
    files = serializers.ListField(
        child=serializers.ListField(child=serializers.FileField()),
        write_only=True,
        required=False,
        allow_empty=True,
        default=[],
    )

javascript reactjs django django-rest-framework file-upload
1个回答
0
投票

使用formData、前端和后端的示例代码(express)

前端编码亮点:

a. blob 对象已被创建来构想文件内容。 参考声明:stmt-1。

b.属性字符串已用于设置 formData 对象中的键。

c.数组中的每个 blob 对象都已单独添加到 formData 中。

以上两点,参考声明:stmt-2。

d。该 API 已在钩子 useEffect 内调用。 参考声明:stmt-3。

e。上传状态已更新为状态变量。 参考声明:stmt-4。

App.js

import { useEffect, useState } from 'react';

export default function App() {
  const [uploadStatus, setUploadStatus] = useState('');

  const someContent = '<q id="a"><span id="b">hey!</span></q>';
  const blob = new Blob([someContent], { type: 'text/xml' }); // stmt 1
  const data = [
    {
      string: 'Somestring1',
      files: [blob, blob],
    },
    {
      string: 'Somestring2',
      files: [blob],
    },
    {
      string: 'Somestring3',
      files: [blob],
    },
  ];

  const formData = new FormData();
  data.forEach((rec) => {
    rec.files.forEach((file) => {
      formData.append(rec.string, file); // stmt-2
    });
  });

  useEffect(() => {
    fetch('http://localhost:3001/api/upload', {
      method: 'POST',
      body: formData,
    })
      .then((response) => response.text())
      .then((data) => setUploadStatus(data)); // stmt-4
  }, []); // stmt-3

  return 'Upload Status : ' + (uploadStatus ? uploadStatus : 'Unknown');
}

后端 - 使用 multer 进行表达

编码亮点

a.前端代码中的multipart-formdata已被nodejs中间件multer接收。有关 multer 的更多信息,请参阅页面 https://www.npmjs.com/package/multer。

服务器.js

const express = require('express');
const multer = require('multer');
const cors = require('cors');
const upload = multer({
  dest: 'uploads',
});

const app = express();
app.use(cors());

app.post('/api/upload', upload.any(), (req, res, next) => {
  console.log(req.files);
  res.send('success');
});

app.listen(3001, () => {
  console.log('Listening...');
});

试运行:

运行前端代码,文件将被上传,并且在后端服务器上,将创建服务器控制台日志,如下所示。

[
  {
    fieldname: 'Somestring1',
    originalname: 'blob',
    encoding: '7bit',
    mimetype: 'text/xml',
    destination: 'uploads',
    filename: 'f94460f91f497bac0c1e0fdc4292eadc',
    path: 'uploads/f94460f91f497bac0c1e0fdc4292eadc',
    size: 38
  },
  {
    fieldname: 'Somestring1',
    originalname: 'blob',
    encoding: '7bit',
    mimetype: 'text/xml',
    destination: 'uploads',
    filename: 'deb237a854b4027a9e106effc236343d',
    path: 'uploads/deb237a854b4027a9e106effc236343d',
    size: 38
  },
  {
    fieldname: 'Somestring2',
    originalname: 'blob',
    encoding: '7bit',
    mimetype: 'text/xml',
    destination: 'uploads',
    filename: '52fd4e96f278f216f339be0f72ce1b6f',
    path: 'uploads/52fd4e96f278f216f339be0f72ce1b6f',
    size: 38
  },
  {
    fieldname: 'Somestring3',
    originalname: 'blob',
    encoding: '7bit',
    mimetype: 'text/xml',
    destination: 'uploads',
    filename: '781e6d3bbf3fb01149fa7fd8e428339d',
    path: 'uploads/781e6d3bbf3fb01149fa7fd8e428339d',
    size: 38
  }
]

后台的uploads文件夹里会有上传的文件。其列表已附在下面。

Uploads folder with files

© www.soinside.com 2019 - 2024. All rights reserved.