1
votes

I've got a basic Sailsjs application which I'm using to learn and I have managed to get an image uploader working with Cloudinary using the below code:

/**
 * FileController
 *
 * @description :: Server-side logic for managing files
 * @help        :: See http://sailsjs.org/#!/documentation/concepts/Controllers
 */

var cloudinary = require('cloudinary');

module.exports = {
    upload: function(req, res) {

        console.log('Request params = ' + req.params);

        var uploadFile = req.file('uploadFile');

        if(uploadFile)
        {
            console.log('Upload file = ' + uploadFile.fd);
        }

        uploadFile.upload(function onUploadComplete(err, files) {
            if(err) {
                return res.serverError(err);
            }
            else if(files.length === 0) {
                return res.badRequest('No file was uploaded.');
            }
            else {

                var imageFile = files[0];

                console.log("image path = " + imageFile.fd);

                console.log('Uploading to Cloudinary, file with path = ' + imageFile.fd + '....');

                // -----------------------------------------------------------------------------
                // Using Cloudinary CDN to handle image uploading
                // -----------------------------------------------------------------------------        
                cloudinary.uploader.upload(imageFile.fd, function(result) {

                    console.log('Finished uploading to Cloudinary, response = %j', result);

                    res.json(result);

                });
            }
        });
    }
};

The only problem doing this way is I'm uploading the image twice essentially.

First time, my iOS app uploads the image to my Sailsjs (Nodejs framework) server.

After finished uploading to my server, it then takes the uploaded file from the file path and then uploads it to Cloudinary CDN.

That's uploading twice...

I don't feel this is the correct way of doing it, but I don't see any other way.

Is it possible to somehow get the POST parameters I sent to my Sailsjs server from my iOS app and upload directly to Cloudinary ?

I've tried using req.file but it says undefined, I assume that is because the file is streamed to the server from my iOS app and not available immediately when my Sailsjs Controller upload function is reached.

Cloudinary does offer an iOS SDK but that would circumvent my server, meaning I can't tie a user account to a profile picture (the URL of the image) for example, right ?

Update 1

Hmmm, ok according to this documentation:

http://cloudinary.com/documentation/node_image_upload

It says to generate a signature:

The upload samples mentioned above allows your server-side Node code to upload images to Cloudinary. In this flow, if you have a web form that allows your users to upload images, the image data is first sent to your server and only then uploaded to Cloudinary.

A more efficient and powerful option is to allow your users to upload images directly from the browser to Cloudinary instead of going through your servers. This method allows for faster uploading and better user experience. It also reduces load from your servers and reduces the complexity of your Node.js applications.

Uploading directly from the browser is done using Cloudinary's jQuery plugin. To ensure that all uploads were authorized by your application, a secure signature must first be generated in your server-side Node.js code.

More investigation required...

Hurmmmm, this is bringing back painful memories of uploading images to Amazon S3 which is what Cloudinary uses.

The steps I remember were:

  1. Request an signed upload URL on server
  2. Server returns JSON containing signed URL to iOS app
  3. iOS app creates a chunked request stream to upload image to server

T_T

1

1 Answers

2
votes

If you prefer, Cloudinary also supports direct (client-side) uploads without the need of a signature. For more information: http://cloudinary.com/blog/direct_upload_made_easy_from_browser_or_mobile_app_to_the_cloud