【问题标题】:Files Uploaded to S3 do not open上传到 S3 的文件打不开
【发布时间】:2023-01-01 16:48:27
【问题描述】:

我正在开发 nodejs api 以将文件上传到我的 AWS s3。我关注了一些在线文章并使用了下面的代码。文件 (images/word/pdf) 成功上传到 s3。但是他们不打开。或者在本地下载打开报错。这里注意到的一件事是,通过我的网络应用程序上传的文件具有元数据内容类型:“application/octet-stream”,而手动上传到 s3 的文件具有元数据内容类型:“image/jpeg”。我错过了什么吗?这是我的 nodejs api:

    app.post("/uploadfile", upload.single("file"), async (req, res) => {
      try {
        console.log(req.file);
        var file = req.file;
    
        const fileStream = fs.createReadStream(file.path);
    
        const params = {
          Bucket: bucketName,
          Key: file.originalname,
          Body: fileStream,
        };
        const result = await s3.upload(params).promise();
        return res.status(200).send({
          ok: true,
          message: "File upload successful",
          location: result.Location,
        });
      } catch (err) {
        res.status(500).send({
          ok: false,
          message: "Failed to upload file. Error: " + err.message,
        });
      }
    });

前端代码:

const [file, setFile] = useState();
  const onSubmit = async (data) => {
    console.log(data);
    const fileData = new FormData();
    fileData.append("upload", file);

    const uploadResult = await uploadFile(fileData);
    console.log(uploadResult);
}

const uploadFile = async (data) => {
  const requestOptions = {
    method: "POST",
    body: data,
  };
  const endPoint = DEV_API_URL + "uploadfile";
  const response = await fetch(endPoint, requestOptions);
  const responseJson = await response.json();
  return responseJson;
};

【问题讨论】:

  • 您是否已验证上传的字节内容是否正确,只是缺少适当的内容类型标头才是问题所在?
  • 看起来字节内容不正确。打开图像时出现“这不是有效的位图文件,或者当前不支持其格式”。 Word 文件给出类似的错误。和 pdf 文件变为空白。但是它们的尺寸似乎是正确的
  • 验证文件内容的更好方法是下载它并与原始(正确)文件进行校验和。或者十六进制转储它并至少比较开始和结束字节。此外,确定源文件的内容类型,然后在调用上传时在 ContentType 中提供该类型。
  • 它们是未打开,还是打开为空白页?
  • 图片、Word 文件出错。 PDF 文件打开但没有内容。

标签: node.js reactjs amazon-web-services amazon-s3 multer


【解决方案1】:

配置 Multer 以将文件存储在内存中:

const multer = require('multer');

const upload = multer({
  storage: multer.memoryStorage(),
});

现在,将文件缓冲区直接传递给 s3。另外,将 ContentType 添加到选项中:

app.post("/uploadfile", upload.single("file"), async (req, res) => {
  try {
    console.log(req.file);
    const file = req.file;

    const params = {
      Bucket: bucketName,
      Key: file.originalname,
      Body: file.buffer,
      ContentType: file.mimetype
    };
    const result = await s3.upload(params).promise();
    return res.status(200).send({
      ok: true,
      message: "File upload successful",
      location: result.Location,
    });
  } catch (err) {
    res.status(500).send({
      ok: false,
      message: "Failed to upload file. Error: " + err.message,
    });
  }
});

【讨论】:

  • 谢谢你的答案。我试过了,但没有用。上传的文件内容似乎有问题。我正在使用 multer。 const multer = require("multer"); const upload = multer({ dest: "uploads/photos/" });
  • 等等,你是把它上传到服务器的uploads/photos/文件夹,然后你又从服务器上传到s3?你在服务器上需要它吗?为什么不将缓冲区直接上传到 s3?
  • 我看到他们遵循这种方法的教程。如何从服务器直接上传到s3?此外,上传到 s3 的文件大小似乎略大于实际大小。我也附上了前端代码。
  • 您可以将 Multer 配置为不上传到服务器,而是将缓冲区保留在内存中。然后,只需将缓冲区传递给 s3。使用当前方法,您的文件将不必要地上传到服务器。
  • 好的,我会试试的。但问题是文件在上传时会损坏。不知何故文件内容没有被保留。
猜你喜欢
  • 2010-12-04
  • 1970-01-01
  • 2021-10-16
  • 1970-01-01
  • 1970-01-01
  • 2023-04-08
  • 2021-10-20
  • 2021-11-28
  • 1970-01-01
相关资源
最近更新 更多