首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Multer-s3在手机上上传空文件

Multer-s3在手机上上传空文件
EN

Stack Overflow用户
提问于 2018-02-23 15:21:56
回答 1查看 1K关注 0票数 5

我正在使用角和穆特-S3上传文件从一个角应用程序到一个节点服务器。桌面上的一切都很好,但由于某种原因,当试图通过我的iPhone 7上传照片时,上传的文件是损坏的。我使用相同的图像,在两个设备上运行相同的流,但是得到不同的结果,所以我假设是因为移动?

以下是试图在手机上打开S3文件时收到的警报

代码语言:javascript
复制
The file “1519398514215-test.png” could not be opened because it is empty.

这是我的密码

代码语言:javascript
复制
var aws = require('aws-sdk');
var path = require('path');
var path3 = path.join(__dirname, "../config/config-aws.json");
var multer = require('multer');
var multerS3 = require('multer-s3');
var request = require('request');

aws.config.loadFromPath(path3);
var s3 = new aws.S3();
var fileName = '';
var uploadM = multer({
  storage: multerS3({
    s3: s3,
    bucket: 'XXXX',
    acl: 'public-read',
    metadata: function (req, file, cb) {
      cb(null, {fieldName: file.fieldname + '.png'});
    },
    key: function (req, file, cb) {
      fileName =  Date.now().toString() + "-" + file.originalname + '.png' ;
      cb(null, fileName)
    }
  })
});



router.post('/', uploadM.array('photos', 3), function(req,res) {
  if (res.error) {
    console.log(error.stack);
    return res.status(400).json({
      message: "Error",
      error: res.error
    });
  }
  const url = 'https://s3-us-west-2.amazonaws.com/XXXX/' + fileName;
  return res.status(200).json({
    fileName: url
  });
});

这是我的客户端

代码语言:javascript
复制
sendImage() {
  const formData: FormData = new FormData();

  this.removeObjectFromCanvas('polygon');


  if (!fabric.Canvas.supports('toDataURL')) {
    alert('This browser doesn\'t provide means to serialize canvas to an image');
  } else {
    // window.open(this.canvas.toDataURL('png'));
    const image = new Image();
    image.src = this.canvas.toDataURL('png');



        const blob = this.dataURItoBlob(image.src);

        const file = new File([blob], 'test.png');


        formData.append('photos', file, 'test');



        this.postFile(formData);
      }


    }

    postFile(file) {
      this.fileService.post(file)
      .subscribe(data => {

      }, error => {
        console.log(error);
      });
    }

更新*

所以发现你可以在手机上调试。看起来我要发送的缓冲区中有数据。我的第一个想法是缓冲区没有发送。

*更新仍然找不出答案。我做了一些研究,它可能与formData和附件有关?但从上面的图片可以看出,两者似乎都很好。将继续研究..。

*更新绝对上传空文件。但只能在手机上?

另外,我在发送到节点服务器之前检查了formData,其中似乎有正确的数据。

*最新情况

好吧,更奇怪的经历。看起来multer-s3正在上传空文件,但是当我在服务器端获取文件并将其返回客户端,然后读取该文件并显示它时,图像将被完美地显示出来。所以formData不是问题所在,而是穆特-S3的问题吗?

*更新--我忘了提到我使用的是人造材料和从画布中获取的图像。我在一些地方读到,可能会出现问题,但正如我前面所说的,当我将文件发送到服务器并将其发送回客户端时,在读取该文件后,它将图像显示得非常完美。

*更新:我尝试将contentType添加到multer方法中,现在只在移动设备上运行时,我收到了一个503服务不可用错误。对于桌面来说,这是很好的。

代码语言:javascript
复制
aws.config.loadFromPath(path3);
var file1;
var s3 = new aws.S3();
var fileName = '';
var uploadM = multer({
  storage: multerS3({
    s3: s3,
    bucket: 'rent-z',
    acl: 'public-read',
    contentType: function (req, file, cb) {
      cb(null, 'image/png');
    },
    metadata: function (req, file, cb) {
      console.log(file);
      cb(null, {fieldName: file.fieldname});
    },
    key: function (req, file, cb) {
      fileName =  Date.now().toString() + "-" + file.originalname;
      file1 = file;
      cb(null, fileName)
    }
  })
}).array('photos', 1);



router.post('/', function(req,res) {
  uploadM(req, res, function (err) {
    if (err) {
      console.log(err);
      return res.status(400).json({
        message: "Error uploading to multer",
        error: err
      });
    }
  console.log('worked');

  if (res.error) {
    console.log(error.stack);
    return res.status(400).json({
      message: "Error",
      error: res.error
    });
  }
  // fs.readFile(req.body, function (err, data) { 
  const url = 'https://s3-us-west-2.amazonaws.com/rent-z/' + fileName;
  return res.status(200).json({
    fileName: url
  });
  // });
  })

});

我甚至试着运行Multer-S3的自动查找mime类型函数,结果也是一样的。

*第4天

从我开始调试这个问题到现在已经96个小时了。没有取得任何进展。还在试图弄清楚为什么它在桌面上工作,而不是移动的。对于任何想要快速总结行为的人来说:

  1. 用户在桌面上上传图像
  2. 用户将图像放在画布上
  3. 使用刻度图像
  4. 用户按sendImage
  5. 这将图像转换为dataUri,然后将blob转换为blob。
  6. 此blob被添加到附加到formData的文件中。
  7. 此formData被发送到nodejs服务器,其中multer-s3中间件成功地将文件上载到s3。
  8. 移动用户尝试
  9. 在步骤7中失败。该文件已上载,但为空。

如果有人想办法继续下去,请告诉我。

EN

回答 1

Stack Overflow用户

发布于 2018-02-27 17:38:25

我会使这是一个“官方”的答案,因为这可能对你的需要。每当我遇到这样复杂的问题时,我的第一个想法通常是“我想知道是否有一个API/SaaS/service可以为我抽象化。”正如您已经发现的,文件上传是很棘手的,特别是当您开始投入大量的设备,我们必须处理这些天。

我不会提到任何特定的服务,但谷歌“文件上传saas”通常会让你成为业界的佼佼者。每月$25-50美元,您可以抽象文件上传到一个非常简单的api调用。您现在不仅节省了时间,而且(假设您选择了一个可靠的提供者),您以后不会再对文件上传感到头疼了。确保文件上传在一百万种不同的设备上工作是SaaS的职责;SaaS的职责是确保S3集成工作,即使S3的api发生变化;SaaS的职责是确保用户在上传失败时看到一条很好的友好信息,等等。我可以花时间为我们的应用程序构建功能,而不是担心文件上传是否在iPhone 47上工作。

但是,我被绑在一个SaaS上,随心所欲地使用他们的价格和功能集“啊,但是你可以把这个问题最小化。”对于我们使用的许多服务,我想做一个包装器/接口/任何您想要称之为它的东西。在文件上传方面,我创建了一个ES6模块:fileUploads.js

在这个模块中,我有一个方法upload。这种方法是做什么的?它只是实现并抽象了fileupload SaaS X的API。如果将来我们希望或需要将SaaS X更改为SaaS Y,我只需在整个应用程序中更改一件事:我的fileUpload.js模块。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48951072

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档