Image not showing immediately after uploading in sails.js

后端 未结 5 2171
轮回少年
轮回少年 2020-12-11 04:43

In my application ,I have stored uploaded images to folder ./assets/uploads. I am using easyimage and imagemagick for storing the images.

In my application, after up

相关标签:
5条回答
  • 2020-12-11 04:46

    Though this question is pretty old but I would like to add a solution which I just implemented.

    Today I spend almost 4 hours trying all those solutions out there. But none helped. I hope this solution will save someone else's time.

    WHY images are not available immediately after uploading to any custom directory?

    Because according to the default Sails setup, you can not access assets directly from the assets directory. Instead you have to access the existing assets that is brought to .tmp/public directory by Grunt at time of sails lift ing

    THE Problems

    1. (Available but Volatile) If you upload a file (say image) anywhere inside .tmp/public directory, your file (image) is going to erase at next sails lift
    2. (Unavailability) If you upload a file in any other custom directory- say: ./assets/images, the uploaded file will not be available immediately but at next sails lift it will be available. Which doesn't makes sense because - cant restart server each time files gets uploaded in production.

    MY SOLUTION (say I want to upload my images in ./assets/images dir)

    1. Upload the file say image.ext in ./tmp/public/images/image.ext (available and volatile)

    2. On upload completion make a copy of the file image.ext to ./assets/images/*file.ext (future-proof)

    CODE

    var uploadToDir = '../public/images'; 
    req.file("incoming_file").upload({
        saveAs:function(file, cb) {
            cb(null,uploadToDir+'/'+file.filename);
        }
    },function whenDone(err,files){
        if (err) return res.serverError(err);
        if( files.length > 0 ){
    
            var ImagesDirArr = __dirname.split('/'); // path to this controller
            ImagesDirArr.pop();
            ImagesDirArr.pop();
    
            var path = ImagesDirArr.join('/'); // path to root of the project
            var _src = files[0].fd             // path of the uploaded file  
    
            // the destination path
            var _dest = path+'/assets/images/'+files[0].filename 
    
            // not preferred but fastest way of copying file
            fs.createReadStream(_src).pipe(fs.createWriteStream(_dest));
            return res.json({msg:"File saved", data: files});
        }
    });
    

    I dont like this solution at all but yet it saved more of my time and it works perfectly in both dev and prod ENV.

    Thanks

    0 讨论(0)
  • 2020-12-11 05:00

    It's a totally normal situation, because of the way Sails works with the assets.

    The thing is that upon sails lift the assets are being copied (including directory structure and symlinks) from ./assets folder to ./.tmp/public, which becomes publicly accessible.

    So, in order to show your images immediately after upload, you, basically, need to upload them not to ./assets/uploads but to ./.tmp/public/uploads.

    The only problem now is that the ./.tmp folder is being rewritten each time your application restarts, and storing uploads in ./tmp/... would make them erased after every sails lift. The solution here would be storing uploads in, for example, ./uploads and having a symlink ./assets/uploads pointing to ../uploads.

    0 讨论(0)
  • 2020-12-11 05:06

    Sails uses grunt to handle asset syncing. By default, the grunt-watch task ignores empty folders, but as long as there's at least one file in a folder, it will always sync it. So the quickest solution here, if you're intent on using the default static middleware to server your uploaded files, is to just make sure there's always at least one file in your assets/uploads folder when you do sails lift. As long as that's the case, the uploads folder will always be synced to your .tmp/public folder, and anything that's uploaded to it subsequently will be automatically copied over and available immediately.

    Of course, this will cause all of your uploaded files to be copied into .tmp/public every time your lift Sails, which you probably don't want. To solve this, you can use the symlink trick @bredikhin posted in his answer.

    0 讨论(0)
  • 2020-12-11 05:07

    I was using node version 10.15.0, and I faced same problem. I solved this by updating to current version of node(12.4.0) and also updated npm and all the node modules. After this, I fixed the vulnerabilities(just run 'npm audit fix') and the grunt error that was coming while uploading the images to assets/images folder was fixed.

    0 讨论(0)
  • 2020-12-11 05:11

    Try to do this:

    • npm install grunt-sync --save-dev --save-exact
    • uncomment the line: // grunt.loadNpmTasks('grunt-sync'); usually it is near to the end of the file /tasks/config/sync.js.
    • lift the App again

    Back to the Original answer

    0 讨论(0)
提交回复
热议问题