uploading image to heroku using node and multer not work

百般思念 提交于 2021-02-08 14:16:16

问题


I am trying to upload image files to Heroku using Node backend and I can make it work, The same exact process work just fine on Localhost testing but after deploying my project to Heroku and testing it, there is an error in the process and the files wont upload

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

SERVER ERROR:

 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

NOTE:

when trying this exact code only using return fetch("http://localhost:3000/uploadcarimage", config);

it work just fine.


回答1:


If you uploaded the code with the images folder is empty, then the images folder is not created in the Heroku server. I've solved this issue by just uploaded my code by adding one image or any file inside the images folder. Now it's working fine :)

Note: The multer can't create a folder if the folder doesn't exist, so you need create it first.




回答2:


I have also got the same problem that same process work just fine on Localhost testing but after deploying my project to Heroku and testing it shows error Access to XMLHttpRequest .....' has been blocked by CORS policy: Request header file x-auth-token is not allowed ' but I have added CORS

So when hit ( heroku logs -t ) in backend Terminal its shows that ' no such file or directory, open '

There's no problem with your code, the matter is that any changes to filesystem last until dyno is shut down or restarted, which means your images are uploaded successfully but when dyno is shut down or restarted Heroku goes back to the filesystem from the most recent deploy. read

store data HEROKU recommend using a database addon such as Postgres (for data) or a dedicated file storage service such as AWS S3 (for static files)

I have use cloudinary + multer to upload images




回答3:


I'm not sure why your uploaded files are not being saved temporarily. But this won't work long-term.

Every time the dynos restarts (this also happens when you change some code in your linked Github repository) or you redeploy your app, the upload folder gets empty(as it is in your Github repository).

Heroku recommends storing uploads on Amazon S3 or something similar like Microsoft Azure. Here's a guide for doing it specifically with Node.js.

Once you've stored your files on S3 you can retrieve them using an appropriate library, depending on how you've configured your bucket.

Get the complete code on how to use Amazon s3 here.




回答4:


I'm not sure, but may be you need set destination as below:

const path = require('path');

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

In my case it solves the problem.

Also need remember, that multer can't create a folder if she doesn't exist, so you need create it first, or if you deploy you app f.e. to heroku set destination as above can help.

In any case you can use my code below (on node sever) - it works:

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



回答5:


There's no problem with your code, the matter is that any changes to filesystem last until dyno is shut down or restarted, which means your images are uploaded successfully but when dyno is shut down or restarted Heroku goes back to the filesystem from the most recent deploy. read this for more details.



来源:https://stackoverflow.com/questions/50566277/uploading-image-to-heroku-using-node-and-multer-not-work

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!