Uploading files made fun with Express js and Blueimp file upload

Tweet about this on TwitterShare on LinkedIn0Share on Google+0Share on Reddit0Buffer this pageFlattr the authorEmail this to someonePrint this page

Uploading files made fun with Express js and Blueimp file upload

In this post, we are going to upload stuff to the server (yeah!!). We will use Express js as our server and Blueimp jQuery file upload plugin to perform the operations.

We will leverage a Node package named blueimp-file-upload-expressjs (written by me). There is already a middleware available, but I wanted to write one on my own, with a few more options. BTW, this is not a middleware, it’s just a plug and play code. 

The final result will be

Screen Shot 2014-05-01 at 3.30.27 pm You can take a dig at this demo here. And you can find the complete code here.

Credits : I have not written any local/server file upload code from scratch. I have taken the node server code from here & cleaned it up a bit. The original code uses imagemagick, and I am planning to use something lightweight and less dependency oriented to enable simple operations like cropping, resizing, filters etc. The search is still on, suggestions are welcome. I have found this awesome node module named Light Weight Image Processor for NodeJS, so far the best light weight image processor.

Contents

Setup

Let’s get started and create our file uploader. First off, create a new folder named fileUploader. Make sure node is installed and then open terminal/prompt here.

Run

Windows Mac/*nix
$ npm install express -g     $ sudo npm install express -g

Once express is installed, we will scaffold a new app.

Run

$ express -e

This will scaffold a new express project with ejs as the templating engine. You can read more about express here. And you should see something like

Screen Shot 2014-05-01 at 3.59.29 pmNow, all you need to do is run

$ npm install

This will install the required dependencies. Once that is done, to run the app

$ node bin/www  or  $ nodemon bin/www

This will start the server and you can navigate  http://localhost:3000 to see the app.

Alternatively you can use a slush generator named slush-express. Run

Windows Mac/*nix
$ npm install gulp slush slush-express -g     $ sudo npm install gulp slush slush-express -g

Then run

$ slush express

to scaffold a new express app. You can select from the following view engines

  1. Jade
  2. Ejs
  3. Hogan
  4. HTML

and the following Style Sheet engines

  1. CSS
  2. LESS
  3. Stylus
  4. SCSS

Once the setup is done, you use run app by executing

$ gulp

This will start the server and you can navigate  http://localhost:3000 to see the app.

Next, stop the server (ctrl + c) and  lets add the file uploader dependency. Run

$ npm install blueimp-file-upload-expressjs --save

Now, in the routes folder, create a new file named uploadManager.js. In index.js, we will load the upload manager passing the router as dependency. Add the below line in index.js after the router declaration

var uploadManager = require('./uploadManager')(router);

Local/Server File Upload

Now, we will configure the Upload Manager. First lets add a set of options on how the uploader should behave in our environment. Add the below code to uploadManager.js

For a Local/Server file upload the minimal options would be

The full blown options would be

Option Description Required Defaults
tmpDir Temporary Upload Directory Y
uploadDir Where the uploaded files need to finally end up Y
uploadUrl Path where the files are uploaded (this will also be the delete route url) Y
maxPostSize Maximum Upload Size N 11 GB
minFileSize Minimum file size to accept an upload N 1 KB
maxFileSize Maximum file size to reject an upload N 10GB
acceptFileTypes Regex with list of file sizes to accept N All
copyImgAsThumb In case of Image uplaods, copy the same image as a thumbnail for preview N True
inlineFileTypes Documents you would like to show inline, for generating a preview. Like Images N Standard Image formats
imageTypes List of Images N  Standard Image formats
imageVersions Dimensions of the resized image N 80×80
accessControl CORS settings N All hosts and methods are allowed
storage Type of storage Y local

As you can see, there are quite a few options you can control.

With more control comes more issues.. I Know!

The above options are tweaked as per our current project. So, you can directly copy these to uploadManager.js. Next, let’s pump in these options to the node package and initialize it. Append the below line to uploadManager.js

Then, we will configure the 3 key routes. Add the below code after the above line

Very Important : The delete method path should be the same as uploadUrl.

Thats it we are all done with our server. Restart your server and navigate to    http://localhost:3000/upload. You should see a JSON response with the empty array of files.

Next, lets take the server to a test drive. Open views/index.ejs and update with the below code

Back to the browser, refresh http://localhost:3000 and you should see a file upload form. Pick a file and click on submit.

The file should get uploaded and you will receive a response like

Screen Shot 2014-05-01 at 4.52.17 pm

Simple right? You can go and check the files folder (and thumbnails folder, if you uploaded an image).

PS : As of now, I am copying the same source image as thumbnail. Looking for simpler alternatives to resize an image in Node.

To build the example that is shown in the demo, we will download the latest Blueimp jQuery file Upload distribution from here then copy the required files to our project.

Update the index.ejs as show here. And copy all the files from the downloaded folder, listed here to public folder in your project.

Restart the server and you are good to go. You can also try integrating the various versions of the plugin listed here. The server side code will be the same for the Basic version as well as the Angular version. Do not forget to change the url in main.js to '/upload'.

The complete example code is available here.

AWS File Upload

To upload a file to AWS, the minimal options would be

and the full blown version would be

 

Option Description Required Defaults
tmpDir Temporary Upload Directory Y
uploadUrl Path where the files are uploaded (this will also be the delete route url) Y
maxPostSize Maximum Upload Size N 11 GB
minFileSize Minimum file size to accept an upload N 1 KB
maxFileSize Maximum file size to reject an upload N 10GB
acceptFileTypes Regex with list of file sizes to accept N All
inlineFileTypes Documents you would like to show inline, for generating a preview. Like Images N Standard Image formats
imageTypes List of Images N  Standard Image formats
accessControl CORS settings N All hosts and methods are allowed
storage Type of storage Y local
strorage.aws AWS config settings Y

As of now, a single instance of uploader is configured to work with a single bucket. Will be adding an option to override the bucket name at runtime.

And then the usual router definitions

This should take care of uploading a file to AWS. Simple?

Do let me know, if you need any more features or options to be exposed. The idea is to make this a comprehensive file upload solution using a Node Server.


Thanks for reading! Do comment.
@arvindr21

Tweet about this on TwitterShare on LinkedIn0Share on Google+0Share on Reddit0Buffer this pageFlattr the authorEmail this to someonePrint this page
  • Abhijeet Khengar

    npm install blueimp-file-upload-expressjs –save not installing properly shows error

  • Ashwini Mendon

    Hey @arvindravulavaru:disqus
    I am getting error while installing blueimp-file-upload-expressjs

    D:Ashwinichatchatnode_modulesblueimp-file-upload-expressjsnode_moduleslwip>if not defined npm_config_node_gyp (node “C:Program Filesnodejsnode_modulesnpmbinnode-gyp-bin\….node_modulesnode-gypbinnode-gyp.js” rebuild ) else (node rebuild )
    Building the projects in this solution one at a time. To enable parallel build, please add the “/m” switch.
    init.cpp
    util.cpp
    buffer_worker.cpp

    and the error list continuous………………..

  • German Viscuso

    Hi! Once a file is uploaded I want to call my own function passing the path (and report on error or success to the user). Where in the source code should I do that?

  • stream

    Hi! Thank you so much for sharing this! Is it possible to upload to cloudinary? I tried to modify the option, storage field in uploadmanager.js. but it seems does not work. so how to find what kind of cloud storage it support?

  • Shikha Singh

    Hey Arvind,

    I’m trying to install the blueimp-file-upload-expressjs, however it gives me an error like this :
    lodash-node@2.4.1: This package has been discontinued in favor of lodash@^4.0.0.

    > lwip@0.0.6 install /Users/shikhasingh/node_modules/blueimp-file-upload-expressjs/node_modules/lwip

    > node-gyp rebuild

    However, I do have lwip and lodash installed.

    Could you help me with how can I upoad an audio file onto my server with a filepath as (https://localhost:8000/uploads/example.mp3). Currently I have been getting it as C://fakepath//

    My front end looks something like this :

    Submit

  • http://www.faronintel.ca/ Faron

    sleek!

  • Michael Owens

    Is your plugin capable of browser based file transfer directly to S3?

    • http://thejackalofjavascript.com/ Arvind Ravulavaru

      This plugin is for Expressjs. You can check out blueimp plugin’s extensions for something like that.

  • http://mikepatt.org Merlin Patterson

    Hello, I’ve gotten your boilerplate code to work. But now I’m attempting to read the file, use its contents to create a new DB entry, and then redirect to the page of that new DB entry.

    Unfortunately, when I redirect, the server crashes with an error that it cannot unlink the temporary file from within the on abort handler. But the new DB entry is created with all the data, the temp file has been removed, and the file has been successfully placed in the files directory.

    I suspect that the file is successfully uploaded, which causes an initial removal, and then the redirect causes the abort handler to trigger, thus causing a second removal, which fails.

    Any suggestions as to how I can successfully redirect without triggering this error?

    • http://thejackalofjavascript.com/ Arvind Ravulavaru

      Hello Merlin,

      Can you please share the screenshot of the issue?

      Thanks.

  • Hellon Canella Machado

    Well, the file was uploaded, but for some reason the response that was rendered is null.

    • zakw

      Hi Hellon,

      I had the same issue. I resolved it by editing uploaderManager.js and changing this:

      uploader.get(req, res, function (obj) {

      res.send(JSON.stringify(obj));

      });

      to this:

      uploader.get(req, res, function (err,obj) {

      res.send(obj);

      I did also update the other functions in the way.

  • gauthu

    Im getting this error when doing an $ npm install blueimp-file-upload-expressjs –save

    C:UsersUser1Desktoptestnode_moduleslwipbuildlwip_decoder.vcxproj(1
    8,3): error MSB4019: The imported project “C:Microsoft.Cpp.Default.props” was
    not found. Confirm that the path in the declaration is correct, and th
    at the file exists on disk.
    C:UsersUser1Desktoptestnode_moduleslwipbuildlwip_encoder.vcxproj(1
    8,3): error MSB4019: The imported project “C:Microsoft.Cpp.Default.props” was
    not found. Confirm that the path in the declaration is correct, and th
    at the file exists on disk.
    C:UsersUser1Desktoptestnode_moduleslwipbuildlwip_image.vcxproj(18,
    3): error MSB4019: The imported project “C:Microsoft.Cpp.Default.props” was no
    t found. Confirm that the path in the declaration is correct, and that
    the file exists on disk.

  • Elia Mörling

    Thanks for providing this. Any updates planned soon? It would be great to have autoSubmit and submitStrategy for example.

  • http://jblanchard.com/ Jeff Blanchard

    Rad process & documentation mate. Thanks for putting it down.

  • Wilson Novido

    Thanks, It worked perfectly. Is there a way to make the upload directory dynamic? I want to pass the directory name as a field.

  • Ace Corpuz

    How to attach it to a model with mongoose? example 1 model with many photos

    • http://thejackalofjavascript.com/ Arvind Ravulavaru

      Can you pls. elaborate? Are your trying to attach photos to a user model?

      • Ace Corpuz

        yeah. multiple photos

  • sabatini

    Hi,
    I tried your beautiful script, but it does not work, you help me please?
    thanks a lot

    this error after upload file:

    SyntaxError: Unexpected token <

    http://www.gepirsrl.com/prova1/index2.html

    • http://thejackalofjavascript.com/ Arvind Ravulavaru

      Hi sabatini. The link you have provided does not work. Also, looking at the response, there is something wrong going on, on the server. This error is causing the server to dispatch a HTML page (probably 500 or 404) which is being parsed by the JS as JSON on the client side. If you can provide the entire error stack, I can help.

      Thanks.

      • sabatini

        Hello Arvind, I changed servers, now works.
        Would you tell me please how I can connect to mysql?
        I want to insert records into the database.

        Thanks

  • SindServRO A casa do servidor

    If u has a error installing in ubuntu, make sure your system has g++ compiler installed.

    Se você está tendo erro instalando em Ubuntu, cheque se tem g++ instalado.

  • Swebert Antony D’mello

    Hi Arvin Ravulavaru,

    When i run npm install. I am getting error

    “C:Program FilesMSBuildMicrosoft.Cppv4.0V120Microsoft.Cpp.Platform.targets
    (64,5): error MSB8020: The build tools for Visual Studio 2010 (Platform Toolset
    = ‘v100′) cannot be found. To build using the v100 build tools, please install
    Visual Studio 2010 build tools. Alternatively, you may upgrade to the current
    Visual Studio tools by selecting the Project menu or right-click the solution,
    and then selecting “Upgrade Solution…”. [C:UsersSwebeeDesktopexpressjs-f
    ileupload-masternode_modulesblueimp-file-upload-expressjsnode_moduleslwipb
    uildlwip_decoder.vcxproj]

    C:Program FilesMSBuildMicrosoft.Cppv4.0V120Microsoft.Cpp.Platform.targets
    (64,5): error MSB8020: The build tools for Visual Studio 2010 (Platform Toolset
    = ‘v100′) cannot be found. To build using the v100 build tools, please install
    Visual Studio 2010 build tools. Alternatively, you may upgrade to the current
    Visual Studio tools by selecting the Project menu or right-click the solution,
    and then selecting “Upgrade Solution…”. [C:UsersSwebeeDesktopexpressjs-f
    ileupload-masternode_modulesblueimp-file-upload-expressjsnode_moduleslwipb
    uildlwip_encoder.vcxproj]

    C:Program FilesMSBuildMicrosoft.Cppv4.0V120Microsoft.Cpp.Platform.targets
    (64,5): error MSB8020: The build tools for Visual Studio 2010 (Platform Toolset
    = ‘v100′) cannot be found. To build using the v100 build tools, please install
    Visual Studio 2010 build tools. Alternatively, you may upgrade to the current
    Visual Studio tools by selecting the Project menu or right-click the solution,
    and then selecting “Upgrade Solution…”. [C:UsersSwebeeDesktopexpressjs-f
    ileupload-masternode_modulesblueimp-file-upload-expressjsnode_moduleslwipb
    uildlwip_image.vcxproj]”

    Is there any solution to install and run the demo application.

    • http://thejackalofjavascript.com/ Arvind Ravulavaru

      Hello Swebert, Try installing lwip (https://github.com/EyalAr/lwip#installation) manually and then try running npm install. There are some pre-requisites for setting up lwip.

  • Ken Lindberg

    Hi Arvin Ravulavaru, Great tutorial, thank you!

    I’m having problems with uploading to S3. The scripts seem to work, no error messages, but nothing gets uploaded to the S3 bucket. If I view the bucket on Amazon’s console, it says that the bucket/folder is empty

    If I upload a file to the bucket using Amazon’s console, I can see the file in the bucket using your example.

    Do the folders noted in the ‘var options = ‘ need to be created in the bucket first? ‘/uploaded/files/’ and ‘/../public/uploaded/tmp’?

    If I create the folders using Amazons’ console, I can see the folders using your example.

    Thank you!

    • http://thejackalofjavascript.com/ Arvind Ravulavaru

      Thanks Ken. When uploading to Amazon, we pick the bucket name from the configs. If that is present, we upload to that location. Also can you check if the following properties exists in the options?

      • Ken Lindberg

        Hi Arvind Ravulavaru,

        Thank you for your reply!

        Yes, all those settings are correct. If I upload a file through the Amazon S3 console, then start your example with Nodejs, your example code then shows the bucket and the file. Of course, there isn’t a thumbnail, but your code is viewing the contents of the bucket.

        If I create a folder using the Amazon S3 console, I can then see the folder by running your example with NodeJs.

        So I know the S3 AWS settings are correct in your snipped above, it’s just the upload that is the problem. I am not able to upload files using your example. I’m sure it is something I’m not doing correctly and am not seeing that.

        Thanks again!
        Ken

        • Ken Lindberg

          Hi Arvind Ravulavaru,

          It turns out it is a matter of permissions on AWS S3. I changed the Bucket Policy to give all access to the IAW user I have in the UploadManager.js file.

          I was able to upload a file to the S3 Bucket.

          The issue now is the thumbnail.

          There is no thumbnail in the Index View. The file is listed there, but the thumbnail is not visible, nor is the thumbnail file in the bucket.

          Can you point me in the right direction to fix that?

          Thank you!
          Ken

          • http://thejackalofjavascript.com/ Arvind Ravulavaru

            Thanks for the update ken. There is an open issue on AWS thumbnail creation https://github.com/arvindr21/blueimp-file-upload-expressjs/issues/36 I have not yet started working on it. If you want any specific feature that is not listed there, you can add it to the issue.

          • Ken Lindberg

            Thank you for your response Arving! Yes, I’ll join in on that issue discussion. I DO need thumbnails in AWS, as well as control of filenames and file location.

            I will be dealing with thousands of files in these uploads, so I’ll need a way to have complete control of the filename and bucket/folder organization of the files.

            Thank you!

          • http://thejackalofjavascript.com/ Arvind Ravulavaru

            Cool! Thanks!

  • abhijeet dhumal

    Hi Arvind Ravulavaru Its really great example I have found after lot of trouble for Image upload with express frame work.

    I have setup sample example, given by you as it is and trying to upload files. But I am getting error message:

    “Error Empty file upload result”.

    I am able to see files are getting uploaded successfully to the server. Can you please help me out in the same?

  • http://www.websiterox.com/ Websiterox

    Nice plugin it really works.

    jQuery File Upload Plugin

  • Yogendra Gupta

    how I can access progress percentage when we are uploading file in chrome . One progress show at the bottom left corner . can anyone tell me how to access that value

  • Yogendra Gupta

    hello ,
    Can I use this demo in asp.net.
    how to change image url in which file.
    and as soon as image and audio both can upload.
    I already change but not working.
    Please let me know solution

    thanks

    • http://thejackalofjavascript.com/ Arvind Ravulavaru

      Hello Yogendra,

      This solution is not for ASP.net. You can find a list of solutions for ASP.net here https://github.com/blueimp/jQuery-File-Upload/wiki#aspnet

      Thanks.

      • Yogendra Gupta

        so how can use in asp.net with file uploading

        thanks

      • Yogendra Gupta

        Hello Arvind,
        I want help from your side we are already discuss about file uploader.. i want to show % time of uploading just like “https://blueimp.github.io/jQuery-File-Upload” this uploader..can you help me.

        • http://thejackalofjavascript.com/ Arvind Ravulavaru

          Hello Yogendra, you want to write a library that calculates the % time? or you need help with the blueimp file uploader? Thanks.

  • dufia

    Hey @Arvind Ravulavaru

    I’am having some issues can you please have a look http://stackoverflow.com/questions/28137770/how-to-fix-this-eacces-error-when-uploading-files-apache-passenger-node

  • uzair

    when i did npm install these are the errors appears

    gyp ERR! configure error
    gyp ERR! stack Error: Can’t find Python executable “python”, you can set the PYT
    HON env variable.
    gyp ERR! stack at failNoPython (C:Program Filesnodejsnode_modulesnpmnod
    e_modulesnode-gyplibconfigure.js:103:14)
    gyp ERR! stack at C:Program Filesnodejsnode_modulesnpmnode_modulesnode
    -gyplibconfigure.js:64:11
    gyp ERR! stack at Object.oncomplete (evalmachine.:107:15)
    gyp ERR! System Windows_NT 6.2.9200
    gyp ERR! command “node” “C:\Program Files\nodejs\node_modules\npm\node_modu
    les\node-gyp\bin\node-gyp.js” “rebuild”
    gyp ERR! cwd C:UsersUzair Ali KhanDownloadsexpressjs-fileupload-master (1)e
    xpressjs-fileupload-masternode_modulesblueimp-file-upload-expressjsnode_modul
    eslwip
    gyp ERR! node -v v0.10.31
    gyp ERR! node-gyp -v v1.0.1
    gyp ERR! not ok
    npm ERR! lwip@0.0.5 install: node-gyp rebuild
    npm ERR! Exit status 1
    npm ERR!
    npm ERR! Failed at the lwip@0.0.5 install script.
    npm ERR! This is most likely a problem with the lwip package,
    npm ERR! not with npm itself.
    npm ERR! Tell the author that this fails on your system:
    npm ERR! node-gyp rebuild
    npm ERR! You can get their info via:
    npm ERR! npm owner ls lwip
    npm ERR! There is likely additional logging output above.

    npm ERR! System Windows_NT 6.2.9200
    npm ERR! command “C:\Program Files\nodejs\\node.exe” “C:\Program Files\nod
    ejs\node_modules\npm\bin\npm-cli.js” “install”
    npm ERR! cwd C:UsersUzair Ali KhanDownloadsexpressjs-fileupload-master (1)e
    xpressjs-fileupload-master
    npm ERR! node -v v0.10.31
    npm ERR! npm -v 1.4.23
    npm ERR! code ELIFECYCLE
    npm ERR!
    npm ERR! Additional logging details can be found in:
    npm ERR! C:UsersUzair Ali KhanDownloadsexpressjs-fileupload-master (1)e
    xpressjs-fileupload-masternpm-debug.log
    npm ERR! not ok code 0

    • http://thejackalofjavascript.com/ Arvind Ravulavaru

      Hello Uzair, you need to have node-gyp for lwip to work. And node-gyp needs python. You can follow the steps here : http://stackoverflow.com/a/21366601/1015046 to install it. Thanks.

  • Praveen

    Good one. I am using a similar functionality.. but we also have a tagging mechanism where a particular image should be attached to a particular item. You have support for videos as well, as said before you are awesome and you rock..

    • http://thejackalofjavascript.com/ Arvind Ravulavaru

      Thanks Praveen.

  • PhucPM

    Hello. Thank you for good module. But I need some choices because my website is web services. There are many customers:
    – Options folder under the username of the client (create folders and upload your username on it.).
    – Encrypt file names when uploading.
    Hope you provide this solution. Thank you!

    • http://thejackalofjavascript.com/ Arvind Ravulavaru

      Hello PhucPM,

      Thanks! If your requirements are custom, you need to fork the repo and add your changes.

      There is already code present for S3 integration. You can use that code and just before you save the file ( https://github.com/arvindr21/blueimp-file-upload-expressjs/blob/master/index.js#L121 ) you can add your changes.

      Thanks.

      • PhucPM

        Thanks Arvind! I will edit it. S3 upload photos but I can not see it in the browser. It’s full download mode. Do you have any way to solve it?

        • http://thejackalofjavascript.com/ Arvind Ravulavaru

          Sorry I did not get you.

  • Pitu Pthree

    how to rename the file before saving into folder, i.e i want to encrypt the file name before it is saved to folder, is there a way to do this

    • http://thejackalofjavascript.com/ Arvind Ravulavaru

      There are 2 ways

      1. Change the file name on the client side js plugin
      2. Fork the repo and modify the Fileinfo class ( https://github.com/arvindr21/blueimp-file-upload-expressjs/blob/master/index.js#L146 ) and encrypt the filename.

      Thanks.

      • Pitu Pthree

        thank you arvind, i have done as suggested by u, now the file name are encrypted which was the requirment in my porject, but if it is a image then the thumbnil are not getting generated ,becz the actual filename is been encrypted , & it doesnt get the extension , so how to tackle this

  • Pitu Pthree

    how to resize the thumbnil , currently it save the same uploded image as a thumbnil, i want to reduce its size & dimension as well, how to get this done, please suggest

    • http://thejackalofjavascript.com/ Arvind Ravulavaru
      • Pitu Pthree

        the code is not working,

        • http://thejackalofjavascript.com/ Arvind Ravulavaru

          Are you using the latest version of the module? This needs to be added to the server config as shown in that example.

          • Pitu Pthree

            ok i will try it again with latest varsion, :)

          • Pitu Pthree

            latest ver gives error

            Error: /home/pitu/node_modules/blueimp-file-upload-expressjs/node_modules/lwip/build/Release/lwip_encoder.node: undefined symbol: _ZN2v816FunctionTemplate3NewEPFNS_6HandleINS_5ValueEEERKNS_9ArgumentsEES3_NS1_INS_9SignatureEEE
            at Error (native)
            at Module.load (module.js:355:32)
            at Function.Module._load (module.js:310:12)
            at Module.require (module.js:365:17)
            at require (module.js:384:17)
            at /home/pitu/node_modules/blueimp-file-upload-expressjs/node_modules/lwip/lib/Image.js:8:19
            at Object. (/home/pitu/node_modules/blueimp-file-upload-expressjs/node_modules/lwip/lib/Image.js:471:3)
            at Module._compile (module.js:460:26)
            at Object.Module._extensions..js (module.js:478:10)
            at Module.load (module.js:355:32)
            at Function.Module._load (module.js:310:12)

          • http://thejackalofjavascript.com/ Arvind Ravulavaru

            Looks like an issue with upgrading the module. Try this

            and then

            Thanks.

  • Pitu Pthree

    thank you arvind,
    how to get file extention as a response,
    error handling while uploading files on server side,
    how to encrypt file name on server side

    • http://thejackalofjavascript.com/ Arvind Ravulavaru

      Hello Pitu, Thanks! Can you please elaborate your questions, did not quite get em’?

      • Pitu Pthree

        how to get file extention, i want to handle error while uploading files how to acheive this, how to encrypt file name before saving on server

        • http://thejackalofjavascript.com/ Arvind Ravulavaru

          For validations, what plugin are using to perform the file upload? The plugin will take care of the validations.
          The module uses the filename while saving it. So if you want to encrypt the file name, you need to do so on the client before the upload begins.

          • Pitu Pthree

            i want to do encryption on server side not on client side is it possible

          • http://thejackalofjavascript.com/ Arvind Ravulavaru

            To encrypt the file, you may need to fork this repo and write your own encryption logic.

  • ppc

    hi arvind, in uploading to user specific folders (and not a generic folder for everyone), its not clear how to set router with delete path in advance, as the user specific folder is constructed using session id or some db unique value for the user(eg. available only after user login). any suggestions regarding it are most helpful. thx

    • http://thejackalofjavascript.com/ Arvind Ravulavaru

      Hello ppc,

      Off the top of my head, you can try this

      Thanks.

      • ppc

        thanks Arvind for that very quick reply. I was looking if the Blue-imp file upload module had any support for user specific deletes. I guess it doesn’t support as the documentation of router.delete says:
        // the path SHOULD match options.uploadUrl

        which it cannot match as it is unknown at the time of routes definition.
        Thanks again for the answer though which I am yet to try.

        • http://thejackalofjavascript.com/ Arvind Ravulavaru

          Hey ppc,

          Yeah, that is when you have a defined path for your uploaded files . In that case, the uploader will take care of the deletion. Here we are explicitly removing the file using fs.unlink() from the specified folder. This is kind of a custom requirement and the uploader code is anytime plug n play only.

          Thanks.

  • Taylor Hardy

    I am trying to modify this to where the image preview remains after upload. Anyone able to point me in the right direction?

    • http://thejackalofjavascript.com/ Arvind Ravulavaru

      Hi @taylor_hardy:disqus as of now, the original image itself acts as the preview. The path of the image url will be same as the thumbnail, if that is what you are asking. Thanks.

  • Somenath

    How do I convert it to REST endpoint to consume files ?

    • http://thejackalofjavascript.com/ Arvind Ravulavaru

      Express is REST in nature, so all the endpoints you are interacting with are RESTful.

      Ex: GET all files
      http://expressjs-fileupload.cloudno.de/upload

      To save a file : POST
      http://expressjs-fileupload.cloudno.de/upload

      You can use any fileuploader on the client side and the server will still work. May be you need to modify the response a bit as per client’s format.

      Thanks.

      • somenath

        when I am trying to use it, I am getting No ‘Access-Control-Allow-Origin’ header is present on the requested resource. What do I need to set in client ? I am using Dronzone.js as client side

        • http://thejackalofjavascript.com/ Arvind Ravulavaru

          Hello Somenath, I have written a tutorial on integrating Dropzone with express file upload here : http://thejackalofjavascript.com/uploading-files-with-dropzone-js-and-express-js

          By Default the allowOrigin is "*" to allow all hosts. Can you check if you have modified the below config in your Express.js options?

          Thanks.

  • Amit

    can you help me with the integration of the same in struts 2…m not able to do it..
    like a sample form page and action code… any basic code will be helpful – amit

  • Fran Miranda

    Does this work with Express 3.x?

    • http://thejackalofjavascript.com/ Arvind Ravulavaru

      Technically yes, have not tested it though!

  • Doomer

    Hi, I’m still new to express and I tried to follow this tutorial step by step unfortunately some module appears to be deprecated and I could not do the tutorial 😐 I really need to be able to do that stuff with those image files the demo page is just awesome plz help me when I run the source code you provided it does nothing I installed all nodejs module and replace a line in app.js this one I read on a forum I had to do that and it worked
    app.use(bodyParser.urlencoded({
    extended: true
    }));
    and then the static-favicon was deprecated and after changing it to serve-favicon, or if I remove it it change nothing the server dont run and just display a pitch black line in the prompt( in windows) and return to prompt with no error nothing plz help me someone I want to do that I need that skill to get a job…

    • http://thejackalofjavascript.com/ Arvind Ravulavaru

      Hello Doomer,

      Can you please clone/download this repo -> https://github.com/arvindr21/expressjs-fileupload, run npm install from inside the cloned folder and then run node bin/www and let me know what you see?

      Or you can share a copy of your code, I can take a look.

      Thanks.

      • Doomer

        npm install is not working outside the nodejs installed directory weird it used to on my olded copmputer maybe I need to reinstall nodejs

        • http://thejackalofjavascript.com/ Arvind Ravulavaru

          Yes, you can try that.

          • Doomer

            trying

          • Doomer

            Ok how do I run npm install from a subfolder npm and node are invalid command or file name anywhere else form the installed folder is this normal ? That the only reason I can’t use express or do any tutorial on it :(

          • http://thejackalofjavascript.com/ Arvind Ravulavaru

            Doomer, Can you uninstall and install node again? The reason you are not able to run node outside the installed folder is because, node/npm are not in your PATH (in environment variables). Uninstalling and Installing node will make sure, node/npm will be saved to path.

            If you are looking for a tutorial on express, you can check out : http://thejackalofjavascript.com/getting-started-with-expressjs

          • Doomer

            Doing so now. Ty for ur time btw.

          • Doomer

            Uninstalling nodejs, and rebooting before reinstalling did’nt fix my PATH. Trying again. Do I need to install it to C:Program Files ? Why won’t it work I guess my only option is to reset windows or something….

          • Doomer

            I’m gonna add the path(both node and npm) manually in windows 8. How should I call my new variable ? Does it changes something ?

          • Doomer

            Wow I fixed the PATH manualy I’m a beast!!!!!

          • Doomer

            Well now eveything works fine. Thank you very much this code is awesome and now I can finaly do the tuts yay!!!! Just one last question, why do I have to run that bin/www I tought I was supposed to run node app.js ?

          • http://thejackalofjavascript.com/ Arvind Ravulavaru

            Great!! Glad you fixed the issue.

            If you open bin/www file, you can see the create server is written here and app.js has only the server configs.

          • Doomer

            Apparently, I still can’t do the tuts because express is an invalid command or filename in prompt did I miss something ? where do I have to type express -e ?

          • Doomer

            I fixed it again it was the very same issue as the one before, had to add ./node_modules./bin to my environment variable Path. Now express-generator work at long last I have gained a level of experience!!!

          • http://thejackalofjavascript.com/ Arvind Ravulavaru

            Great!!

  • Mark Chiles

    Hey @arvindravulavaru:disqus. Have you extended this to potentially allow the creation of folders inside the bucket? Thanks, Mark

    • Mark Chiles

      Actually I found that if you updated the line 113 in node_modules/blueimp-file-upload-expressjs/index.js, you can add a new folder fairly easily, and the files will be uploaded there.

      Change
      “Bucket: options.storage.aws.bucketName,”
      to
      “Bucket: options.storage.aws.bucketName + ‘/folderName’,”

      • http://thejackalofjavascript.com/ Arvind Ravulavaru

        @markchiles Thanks for the suggestion and the solution :). Will expose this as an option soon.

        • Mark Chiles

          @arvind awesome! I think if there was a quick way to pull in a GET or POST variable from the URL, could dynamically create folders on the fly. Know of a quick way to do that? Thanks!

          • http://thejackalofjavascript.com/ Arvind Ravulavaru

            @markchiles There is an issue with uploading additional data to server using the current file upload code. Once that is resolved, I guess we can implement this. – Thanks.

  • dufia

    Hey @arvindravulavaru:disqus !

    Thank you for the package! You rock! Is it passible to generate unique filename before saving it on the server? Thanks!

    • http://thejackalofjavascript.com/ Arvind Ravulavaru

      Hey @dufia:disqus . Thanks! Let me see if I can expose that as an option.

      • http://thejackalofjavascript.com/ Arvind Ravulavaru

        @dufia:disqus looks like there is no easy way to expose it. You need to fork the repo and make your own changes on the code.

        • dufia

          Arvind Ravulavaru

          Ok, I have another problem and maybe you could help.

          My upload code worked just fine on a localhost but there is an issue when I checked it on the server. Its weird… When I upload large files like 150KB+ it works every time but if the file is smaller it works like every 10-20th time.

          The developer tools says the request is pending and then it simply timeouts. I check the logs and the error is: [Error: MultipartParser.end(): stream ended unexpectedly: state = PART_DATA]

          Please help :)

        • dufia

          @arvindravulavaru:disqus

          Ok, I have another problem and maybe you could help.

          My upload code worked just fine on a localhost but there is an issue when I checked it on the server. Its weird… When I upload large files like 150KB+ it works every time but if the file is smaller it works like every 10-20th time.

          The developer tools says the request is pending and then it simply timeouts. I check the logs and the error is: [Error: MultipartParser.end(): stream ended unexpectedly: state = PART_DATA]

          Please help :)

          • http://thejackalofjavascript.com/ Arvind Ravulavaru

            @dufia:disqus Looks like this is an issue from the client end. The connection is closed before all the data is received https://github.com/felixge/node-formidable/issues/281 .

          • dufia

            @arvindravulavaru:disqus
            I was pretty sure that the code is fine, so I tested it on Nodejitsu. It works properly, must be my providers issue. How silly is that, large files are fine, small files won’t upload. It somehow receives progress data (100% uploaded) and then fails somewhere. Thanks anyway.

          • http://thejackalofjavascript.com/ Arvind Ravulavaru

            Yeah, I know. Happens mostly on shared hosting services. They have pretty strict rules on resource consumption.

            Glad the issue is resolved! Thanks.

  • ankur

    Hi Arvind, I have request. Can you please show how to do this using angularjs?

    By the way, thanks a lot for this tutorial. I have been trying to get the blueimp file upload working for the past few days without any success. This tutorial made it so easy.

    • http://thejackalofjavascript.com/ Arvind Ravulavaru

      Thanks Ankur.

      The Angular implementation is pretty simple. Try the below steps

      1. Download this repo : https://github.com/blueimp/jQuery-File-Upload
      2. Open js/app.js and replace

      with

      3. Host the same on a *AMP server and open angularjs.html (with a http url not file:///)

      This should do the trick.

      Thanks!

      • ankur

        Thanks for the quick reply!

        So, you mean that I will have to run 2 servers, one for hosting the uploader and the other for my application? Please correct me if I am wrong.

        • http://thejackalofjavascript.com/ Arvind Ravulavaru

          You can dump all the files inside the express public folder as we did in the above example. I was making sure there was no confusion.

          All that matters is, the file needs to be hosted and accessed and not via file:///

          • ankur

            I will try this out.Thanks for your help and the prompt replies. It’s very much appreciated. Keep up the good work. Cheers!

          • http://thejackalofjavascript.com/ Arvind Ravulavaru

            Thanks!

  • Karan

    Can this be used for building a REST API as well? I want to allow an Android/iOS app to be able to upload/download images.

    • http://thejackalofjavascript.com/ Arvind Ravulavaru

      Hello Karan, You can directly upload files to the end point http://expressjs-fileupload.cloudno.de/upload. This can be done with above approach.

      • Karan

        How would you download an image?

        • http://thejackalofjavascript.com/ Arvind Ravulavaru

          Hello Karan, If I am not wrong, you can download the resource when you click on the name hyperlink.

          For files that are other than images, you can download them as mentioned above. And for images, you can either show them in a gallery plugin on clicking the hyperlink or else, you can remove the data-gallery attribute on the href in the download template here : https://github.com/arvindr21/expressjs-fileupload/blob/master/views/index.ejs#L132 to make them downloadable.

          Thanks.

  • Ben

    Hi Arvind,
    first of all, I love your tutorial and the work you’ve done. Setup was easy and it works really well. I have one question though:
    I need a button that copies the URLs of the items where the checkbox on the right is toggled and outputs it somewhere on the page so that you can copy the URLs of a bunch of pictures in one go (to e-mail them all or do whatever with it).
    As I am new to jQuery, how would I go about doing this?

    • http://thejackalofjavascript.com/ Arvind Ravulavaru

      Hello Ben. Thanks much. Glad I could be of help.

      You can always do something like this

      var allLinks = [];
      $(‘input[type=checkbox]’).each(function (index, ele) {
      if(index == 0) return; // first checkbox – check all — skip it
      if($(ele).prop(‘checked’)) { // if the checkbox is check
      var link = $(ele).parents(‘tr’).find(‘a’).attr(‘href’); // get the href link
      console.log(link); // you can perform your operation here or used the allLinks array
      allLinks.push(link);
      }
      });
      // access allLinks to get all the links.

      You can copy the above code and paste it in the demo page — http://expressjs-fileupload.cloudno.de. I have uploaded 4 images for now.

      Do let me know if you face issues. Thanks.

      • Ben

        Thank you very much for your quick reply! It works perfectly and I was also able to learn something from the code you provided! :)

        One last question before I leave: Is there any way to reverse the order of the list? Right now, new files appear at the bottom. I’d prefer it at the top.

        • http://thejackalofjavascript.com/ Arvind Ravulavaru

          Hello Ben. Thanks!. When you send the data from the server, you can arrange them in any order you want and send it.

          In the uploadManager, https://github.com/arvindr21/expressjs-fileupload/blob/master/routes/uploadManager.js#L35

          You can tamper with the “obj”, which will be a array of files that show up on page load.

          • Ben

            Hi Arvind,
            thanks for taking the time to help me out.

            If obj is an array, shouldn’t this work?
            var reversedObj = obj.reverse();

            However, I get an error: Object # has no method ‘reverse’.

            Does it get “converted” to an Array at some other/later point?

          • http://thejackalofjavascript.com/ Arvind Ravulavaru

            Hello Ben. Not an issue.

            The obj that is returned from the file upload will look like

            To extract the list of files, you need to access the “files” property of the object like

            now you can perform the Array operation like

            and it should work as expected!

            The completed code would be

  • Gokhan Aykan

    Thanks for the excellent article.
    I have two problems.
    1. I want to send bucket name as parameter. So I add a hidden input field to form.
    But cannot get the field data in server.
    I tried to add bucket name as /upload/bucket_name and add param to nodejs as /upload/:bucket
    Bu this time I get 505. Any comment ?
    2. I want serve html from a different server not from nodejs server.
    So I use ‘http://node_server:3000/upload’ on the form.
    But again it cannot find the server.

    Thanks in advance..

    • http://thejackalofjavascript.com/ Arvind Ravulavaru

      @gokhanaykan:disqus Thanks!

      #1 There is some issue with Expressjs, where extra data added to the form are not received at the server. There were a couple of issues reported, but did not get time to look at it.
      Your solution seems to be good, but a HTTP 505 means that the Express server is not able to recognize the HTTP version of your request. I am assuming this is because, you are hosting your web page on Server A and Upload code on Server B. (If you can share a runnable/github code, I can take a look)

      For now, since the bucketname is not sensitive data, I would advise you to send that as a cookie to the server and access it using req.cookie. Can you check if this works?

      #2 Let us say that you are serving your html from a WAMP/LAMP or MAMP server, which is running at 9000. So the URL that loads your upload component page is http://localhost:9000/myUploadPage.html.

      Next, let us assume that the Express server that has the upload endpoint is running on 3000 ( you can test that by firing http://localhost:3000/upload and you should see a JSON array of files ex: http://expressjs-fileupload.cloudno.de/upload ).

      Now, the form tag on myUploadPage.html will have a form action=”http://localhost:3000/upload”.

      Now, making sure that both the servers are running, try and upload the file. If you have issues with http://localhost:3000/upload try uploading to http://expressjs-fileupload.cloudno.de/upload (I think it should work).

      Thanks.

      • Gokhan Aykan

        Thanks. I ‘ll try today and share the gist. But in my another application, I pass the hidden fields.
        Regards.

  • Alexander Kuales

    Thanks alot for this tutorial! I have a problem regarding aws though – everything works fine on local.
    files are sent to s3.amazonaws.com/myBucketXYZ/…
    I wanted to give it a try and change it to myBucketXYZ.s3.amazonaws.com/… but I unfortunately changes in the node-module index.js are ignored.
    As far as I found out the first URL should actually work as well, but maybe only with the default region, not with eg. Ireland.
    Any suggestions are much appreciated! Thank you very much!

    • http://thejackalofjavascript.com/ Arvind Ravulavaru

      @alexanderkuales:disqus Thanks! And Glad I could be of help.

      If I understood your question correctly, you want select a region when you configure AWS? like
      { “accessKeyId”: “akid”, “secretAccessKey”: “secret”, “region”: “us-west-2″ }

      • Alexander Kuales

        Thank you for your fast reply!
        Unfortunately I can only assume that this would work – i’ve read the aws docs and this was suggested, as well as adding the bucketname as subdomain.. I wanted to tweak the index.js (Line 239) of the bluimp-file-upload-expressjs module to do so, but the changes weren’t recognized (i’m working with grunt -> nodemon recognized the change).

        • http://thejackalofjavascript.com/ Arvind Ravulavaru

          What you can try out is replace Line 239 :

          sss = {url : (options.ssl ? ‘https:’ : ‘http:’)+’//s3.amazonaws.com/’+options.storage.aws.bucketName+’/’+o.Key }

          with

          sss = {url : (options.ssl ? ‘https:’ : ‘http:’)+’//’+options.storage.aws.bucketName+’.s3.amazonaws.com/’+o.Key }

          in the node_modules/blueimp-file-upload-expressjs/index.js. Then restart the server, the new url should reflect.

          If you are not sure as what URL is being passed, add a console log after the above statement like
          console.log(“URL >>> “,sss);

          If this works, I can add another option at module level.

          Also do let me know, if you would like the region setting too.

          Thanks,
          Arvind.

          • Alexander Kuales

            I have already tried to output a console log within the fileUploader.get function.. it never got called.
            Which makes sense, as the image gets sent to /upload via post (i copied the uploadManager.js file exactly from your tutorial) – but where does the fileUploader.post function get the amazon URL from?

          • http://thejackalofjavascript.com/ Arvind Ravulavaru

            You will find that on line 239 node_modules/blueimp-file-upload-expressjs/index.js file. the above steps will help you replace the url inside the module to the subdomain format.

          • Alexander Kuales

            I dug a little deeper now.. so it seems there is a problem with the bucket or it’s credentials.. as if i’m calling http://localhost:3000/upload a get an error saying “PermanentRedirect: The bucket you are attempting to access must be addressed using the specified endpoint. Please send all future requests to this endpoint.” in my console.
            so I am guessing this was the problem all along. so sorry for bothering you with this… I feel like a noob now….

          • http://thejackalofjavascript.com/ Arvind Ravulavaru

            No problem. Glad the issue is sorted out.

          • Alexander Kuales

            so.. that took a while to figure out, but it was the region problem – as expected. I added a region field and changed line 70 in the index.js to
            AWS.config.update({accessKeyId: options.storage.aws.accessKeyId, secretAccessKey: options.storage.aws.secretAccessKey, region: options.storage.aws.region});

            now everything works as expected.
            Thank you very much again for your support and the good work!

          • http://thejackalofjavascript.com/ Arvind Ravulavaru

            @alexanderkuales:disqus Thanks for the feedback. Added a region support to the configs (v 0.2.7). If you are sure of your region, you can set it up in the configs like

            aws : {
            accessKeyId : ‘XXXXXXXXXXXXXXXXXXXXXXXX’,
            secretAccessKey : ‘XXXXXXXXXXXXXXXXXXXXXXXX’,
            region : ‘us-west-2′, //make sure you know the region, else leave this option out
            bucketName : ‘XXXXXXXXXXXXXXXXXXXXXXXX’
            }

            If there is no region set, the value would be null & the default region of the bucket would be selected.

            Thanks,
            Arvind.

          • Alexander Kuales

            Great Stuff, thanks for adding this to the repo.

            Unfortunately I’m now stuck with another aws problem: I cannot figure out how to put files to subfolders correctly like /uploads/images.jpg… initially it’s sending files to the bucket-root.

            what I tried to do was adding ‘uploads/’+remoteFilename to the “KEY” in the s3.putObject – this copied the image, as I wanted, in the /uploads/images.jpg.. but somehow, tweaking this part of the code like that, just doesn’t seem right.

            I’ve tried different approaches setting the uploadUrl in the options but I had no luck.
            Would you recommend creating a bucket just for the websites uploads?

          • http://thejackalofjavascript.com/ Arvind Ravulavaru

            Can you try the bucketname+foldername as the bucketName in the config?

            aws : {
            ….
            bucketName : ‘bucketname/folder/’
            }

          • Alexander Kuales

            Awesome! Upload works like a charm with these settings. THANKS!
            It’s not important for my site, but I figured out that with bucketName : ‘bucketname/folder/’ http://localhost:3000/upload throws an error (NoSuchKey)

          • http://thejackalofjavascript.com/ Arvind Ravulavaru

            @alexanderkuales:disqus cool!

  • Michel

    Is there a way to disable the creation of thumbnails without editing the Node.js code ?

    • http://thejackalofjavascript.com/ Arvind Ravulavaru

      Hello Michel, If the thumbnails are disabled, there will not be a preview available, once the upload completes. Do you want that?

      Thanks,
      Arvind

      • Michel

        I found annoying that the uploaded files got duplicated since the thumbnail creation functionality was disabled / not finished. So I just used a link to the real image on server with small height as a preview.

    • http://thejackalofjavascript.com/ Arvind Ravulavaru

      You can always set copyImgAsThumb : false.

      var options = {
      tmpDir: __dirname + ‘/../public/uploaded/tmp’,
      uploadDir: __dirname + ‘/../public/uploaded/files’,
      uploadUrl: ‘/uploaded/files/’,
      copyImgAsThumb : false,
      storage : {
      type : ‘local’
      }
      };

    • Michel

      I tried to set copyImgAsThumb to false, but the thumbnails keep getting created.

      • http://thejackalofjavascript.com/ Arvind Ravulavaru

        Merged your PR. Thanks for the contribution.

  • Andy

    Unfortunately you can not specify the directory to upload

    • http://thejackalofjavascript.com/ Arvind Ravulavaru

      Hello Andy,

      I have recently updated this post. If you are trying to upload a file to local/server, you can use uploadDir option to mention the path where you want to upload the files to.

      Ex:
      uploadDir: __dirname + ‘/../public/uploaded/files’

      Thanks,
      Arvind.

      • Pouya ataei

        Hello Arvind,

        I”m hardly trying to run this command ( npm install blueimp-file-upload-expressjs –save ), and I keep getting an error stating that node-gyp rebuild is failing on my system. I went through many documentations and installed all the requirements such as python, visual c++, sdk, setting environment variables and anything else I could find over the internet. I’m still getting the same error, and it’s terribly annoying. Please do let me know if you have any idea about this… Thanks In advance

        • http://thejackalofjavascript.com/ Arvind Ravulavaru

          Hello Pouya, Try installing lwip (https://github.com/EyalAr/lwip#installation) manually and then try installing the file uploader module. There are some pre-requisites for setting up lwip.