【问题标题】:uploading image to heroku using node and multer not work使用节点和multer将图像上传到heroku不起作用
【发布时间】:2018-11-07 01:00:21
【问题描述】:

我正在尝试使用 Node 后端将图像文件上传到 Heroku,我可以让它工作,相同的过程在 Localhost 测试中工作得很好,但是在将我的项目部署到 Heroku 并对其进行测试后,过程中出现了错误而且文件不会上传

后端:

let storage = multer.diskStorage({
    destination: function (req, file, cb) {
      cb(null, './uploads')
    },
    filename: function (req, file, cb) {
      cb(null, file.originalname)
    }
  })

const upload = multer({storage: storage})


router.post('/', upload.single('carImage') ,(req, res) => {

    console.log(req.file);    
    let todayArr = today.slice(0, 4);

})

正面:

  uploadImageToServer = (imagePath, fileName) => {
      const photo = {
        fieldname:'carImage',
        uri: imagePath,
        name: fileName,
        type: 'image/jpeg',
      };
      const data = new FormData();
      data.append('carImage', photo);
      const config = {
        method: 'POST',
        body: data,
      };
      return fetch("https://foo.herokuapp.com/uploadcarimage", config);
    }

      this.uploadImageToServer(this.state.path, `${this.state.car.plate.toString()}-${date.join('-')}.jpg`)
        .then(resp => resp.json())
        .then(json => console.log(json))
        .catch(err => console.log(err))

服务器错误:

 POST /uploadcarimage 500 2172.411 ms - 229
2018-05-28T11:39:53.045824+00:00 heroku[router]: at=info method=GET path="/6866866-Mon-May-28-2018.jpg" host=pure-journey-53428.herokuapp.com request_id=d6f6dfff-af19-4a6f-8f76-a0f14e3f812e fwd="12.34.567.890" dyno=web.1 connect=0ms service=2ms status=404 bytes=368 protocol=https

注意:

仅使用 return fetch("http://localhost:3000/uploadcarimage", config); 尝试此确切代码时

它工作得很好。

【问题讨论】:

    标签: javascript node.js heroku multer


    【解决方案1】:

    我不确定,但您可能需要如下设置目的地:

    const path = require('path');
    
    destination: function (req, file, cb) {
         cb(null, path.resolve(__dirname, 'build'))
    }
    

    就我而言,它解决了问题。

    还需要记住,如果 multer 不存在,则无法创建文件夹,因此您需要先创建它,或者如果您部署应用程序 f.e.到 heroku 设置目的地如上所述可以提供帮助。

    在任何情况下,您都可以使用我的代码(在节点服务器上)——它可以工作:

    const multer = require('multer');
    const path = require('path');
    
    if (process.env.NODE_ENV === 'production') {
      var storage = multer.diskStorage({
        destination: function (req, file, cb) {
          cb(null, path.resolve(__dirname, 'build'))
        },
        filename: function (req, file, cb) {
          cb(null, file.fieldname + '_' + Date.now() + '_' + file.originalname)
        }
      })
    } else {
      var storage = multer.diskStorage({
        destination: function (req, file, cb) {
          cb(null, path.resolve(__dirname, 'uploads'))
        },
        filename: function (req, file, cb) {
          cb(null, file.fieldname + '_' + Date.now() + '_' + file.originalname)
        }
      })
    }
    
    const uploads = multer({ storage: storage });
    
    app.use(uploads.any());
    if (process.env.NODE_ENV === 'production') {
      app.use(express.static(path.resolve(__dirname, 'build')));
    } else {
      app.use(express.static('./public'));
    }
    
    //if you need to download (after upload) files in cloudinary 
    const cloudinary = require('cloudinary');
    cloudinary.config({
        cloud_name: '...',
        api_key: '...',
        api_secret: '...'
    });
    //if you need to del files after upload
    const fs = require('fs');
    
    router.post('/admin/create-product-images', (req, res, next) => {
    
        let urls = [];    
    
        async function sendImagesToCloudinary() {
            for (let file of req.files) {
                await cloudinary.uploader.upload(
                    file.path,
                    {
                        public_id: `${Date.now()}`,
                        resource_type: 'auto'
                    }
                ).then(result => {
                    //del files after upload on cloudinary
                    fs.unlink(file.path, function (err) {
                        if (err) {
                            console.log(err);
                        }
                    });
                    urls.push(result.url);
                })
                .catch(err => {
                    console.log(err);
                });
            }
            res.json(urls);
        }
    
        sendImagesToCloudinary();
    });
    

    【讨论】:

      【解决方案2】:

      您的代码没有问题,问题是对文件系统的任何更改都会持续到 dyno 关闭或重新启动,这意味着您的图像已成功上传,但是当 dyno 关闭或重新启动时 Heroku 从最近的部署。阅读this了解更多详情。

      【讨论】:

        【解决方案3】:

        我也遇到了同样的问题,同样的过程在 Localhost 测试中工作得很好,但是在将我的项目部署到 Heroku 并测试它之后显示 错误 Access to XMLHttpRequest .....' has been blocked by CORS policy: Request header file x-auth-token is not allowed' 但我已添加 CORS

        所以当在后端终端中点击(heroku logs -t)时,它会显示'没有这样的文件或目录,打开'

        您的代码没有问题,问题是对文件系统的任何更改都会持续到 dyno 关闭或重新启动,这意味着您的图像已成功上传,但是当 dyno 关闭或重新启动时 Heroku 从最近的部署。 read

        存储数据 HEROKU 建议使用 Postgres(用于数据)等数据库插件或 AWS S3(用于静态文件)等专用文件存储服务

        我已经使用 cloudinary + multer 上传图片

        【讨论】:

          【解决方案4】:

          如果您上传代码时 images 文件夹为空,则图像文件夹不会在 Heroku 服务器中创建。 我通过在图像文件夹中添加一个图像或任何文件来上传我的代码,从而解决了这个问题。现在它工作正常:)

          注意:如果文件夹不存在,multer无法创建文件夹,需要先创建。

          【讨论】:

          • 我使用的是express-fileuploader 并且遇到了同样的问题。将图像插入文件夹为我修复了它。
          • 是我的问题,写了一个命令来创建我的上传文件夹,如下所示在我的 package.json "scripts" : { "heroku-postbuild" : "mkdir my-upload-folder" }
          【解决方案5】:

          我不确定为什么您上传的文件没有暂时保存。 但这不会长期有效。

          每次 dynos 重新启动(当您更改链接的 Github 存储库中的某些代码时也会发生这种情况)或重新部署您的应用程序时,上传文件夹会变空(就像它在您的 Github 存储库中一样)。

          Heroku 建议将上传内容存储在 Amazon S3 或类似 Microsoft Azure 之类的东西上。这是一个guide,专门用于使用 Node.js。

          将文件存储在 S3 上后,您可以使用适当的库检索它们,具体取决于您配置存储桶的方式。

          获取有关如何使用 Amazon s3 here 的完整代码。

          【讨论】:

            猜你喜欢
            • 2016-06-08
            • 1970-01-01
            • 2020-10-26
            • 2020-12-24
            • 2020-03-22
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-12-25
            相关资源
            最近更新 更多