使用节点将图像上传到heroku并且multer不起作用

时间:2018-05-28 12:17:56

标签: javascript node.js heroku multer

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

BACKEND:

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);

})

FRONT:

  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);

尝试此确切代码时

它运作得很好。

5 个答案:

答案 0 :(得分:4)

如果您上载的代码是 images文件夹为空,则不会在Heroku服务器中创建images文件夹。 我已经解决了这个问题,只需在图像文件夹中添加一个图像或任何文件来上传代码即可。现在一切正常:)

注意:如果该文件夹不存在,则无法创建文件夹,因此您需要先创建它。

答案 1 :(得分:1)

我也遇到了同样的问题,即在Localhost测试中相同的过程也可以正常工作,但是将我的项目部署到Heroku并对其进行测试后显示 错误由于CORS策略阻止了对XMLHttpRequest .....的访问:不允许请求头文件x-auth-token',但是我添加了CORS

因此,当在后端终端中命中(heroku logs -t)时,表明“没有这样的文件或目录,请打开”

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

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

我使用cloudinary + multer上传图像

答案 2 :(得分:1)

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

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

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

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

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

答案 3 :(得分:0)

我不确定,但是可能您需要按以下方式设置目的地:

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();
});

答案 4 :(得分:0)

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