1

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 Answer 1

2

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

Sign up to request clarification or add additional context in comments.

2 Comments

Yes I've had a chat with the Cloudinary support and it appears there is a way to upload using a unsigned URL. Only problem is when I need to tie a profile photo URL to a "User" entity on my server. There is a notification URL which fixes that part. The last question is, how do I generate the unsigned URL ? If I have to tell my server to generate it, then it's virtually no different to using a signed URL, in that case, I would prefer to generate a signed URL on server and then return that to app to upload and use notifcation URL.
Every upload call immediately returns a response which includes a JSON with the details of the uploaded image's details, including the public_id, url and more. You don't have to use a servers-side to generate the unsigned upload code, in the blog I mentioned earlier, at the first two code snippets, you can click on the 'iOS' tab to see a client-side code example.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.