3

Scenario

Imagine we are writing a web application with a simple registration page containing something like the following:

  • Name
  • Email
  • Password
  • Profile Picture

OK, great, next the user hits "Create Profile". Ideally we would like the following to happen..

  1. Our image to be resized on the client (using their cpu)

  2. To post that image right over to S3, into a unique resting place. (without going through our hosting server costing us dyno's and precious time on our over worked single threaded rails app).

  3. To know when our image has been successfully uploaded to S3.

  4. Once the image is safe and sound, submit a second form through to our cloud server with the name, email, password and path to our troublesome image.

Question

Does this approach sound about right?

Also, does anybody know of any examples of how to do this in Rails? Ideally I am trying to find a way to abstract the differences from the user so they only have to hit one save button since that's all they care about.

I have found bits and pieces but nothing that ties it all together.

So far, I have been considering using SwfUpload as outlined in some of these articles...

http://vimeo.com/11363680

https://github.com/blueimp/jQuery-File-Upload/wiki/Upload-directly-to-S3

I am a hobbyist at best when it comes to Rails, just wondering if there is a well thought out pattern for this? Everything I have seen so far (as great and helpful as that work is) only seems to get half way there.

I don't know it just feels like I am fighting hard to do something that people must deal with every day during modern development, I feel like I am missing something...

Steve Sheldon
  • 6,421
  • 3
  • 31
  • 35
  • I guess you found this already, but with [s3-swf-upload-plugin](https://github.com/nathancolgate/s3-swf-upload-plugin) you can upload to S3 directly. Resizing is usually done on the server, so I don't think this is something people deal with every day in modern development. โ€“ Mischa Apr 24 '12 at 06:15
  • Check [this](http://stackoverflow.com/a/20318266/1875166). โ€“ alexcasalboni Dec 01 '13 at 22:56

2 Answers2

0

Correct me if I'm wrong, but it sounds like you want to do everything in the client (which means JavaScript).

I believe there's a way to resize the image using Canvas, but 1) it's not going to look very good (unless it's simple cropping), 2) this assumes that the user has a modern browser, and 3) if you do use Canvas you'll need to convert it back into an image once you've finished processing it, which means you need to send the data somewhere to be stored in a file, which means a hit to your server.

Posting right to S3 is fine using a form that POSTs directly to the S3 API, except that you don't know when the image has been uploaded because control leaves the page and never comes back. This means you have to do it using Ajax... except then you run into the cross-origin policy. You may be able to do this with the iframe + postMessage trick, although that would be a hit to your server. So I think the only way to solve this problem is to use Flash, รก la Gmail's attachment uploader (which seems like the road you are going down anyway). If you go down that route, then you may have to change the workflow a bit -- i.e. instead of having the image get uploaded on submit and then waiting until it is submitted before proceeding, have the user manually upload the image and block the submit button until the image is uploaded. (It's a bit more usable that way anyway, IMO.)

So I'm not sure if there's a complete solution to your problem short of changing hosting providers or adding more servers, but there are some ideas at least.

Elliot Winkler
  • 2,336
  • 20
  • 17
  • I am thinking of having the file auto upload after the user picks the file with a progress bar and the submit button locked until it completes ... Or honestly, sucking it up and putting it through my regular hosting box until I absolutely have to go direct to S3. In other words, don't optimize until I need to. For all I know the site could crash and burn with 10 users and I spent a week working on a fancy image uploader for nothing :-) โ€“ Steve Sheldon Apr 24 '12 at 06:38
0

Came across this while searching for a different problem: what you can do with S3 is use the browser upload and post to a hidden iframe. By default when using the browser upload you can specify a redirect location. You can then have the redirect location invoke javascript that submits the registration form. I successfully did this with an image file I wanted uploaded: I then call my heroku dyno which pulls the file off S3 in a background task, generates a thumbnail and then posts the thumbnail back to S3.

Resizing in the browser is going to be non-trivially difficult to do, however. See Resizing an image in an HTML5 canvas for one possible solution.

Community
  • 1
  • 1
Femi
  • 64,273
  • 8
  • 118
  • 148