Search code examples
file-uploadnginxcross-domainsame-origin-policyvk

What is the best way to upload files to another domain from a browser?


I am creating a web service of scheduled posts to some social network.
Need help dealing with file uploads under high traffic.

Process overview:

  • User uploads files to SomeServer (not mine).
  • SomeServer then responds with a JSON string.
  • My web app should store that JSON response.

Option 1: Save, cURL POST, delete tmp
The stupid way I made it work:

  1. User uploads files to MyWebApp;
  2. MyWebApp cURL's the file further to SomeServer, getting the response.

Option 2: JS magic
The smart way it could be perfect:

  1. User uploads the file directly to SomeServer, from within an iFrame;
  2. MyWebApp gets the response through JavaScript.

But this is(?) impossible due to the 'Same Origin Policy', isn't it?

Option 3: nginx proxying?
The better way for a production server:

  1. User uploads files to MyWebApp;
  2. nginx intercepts the file uploads and sends them directly to the SomeServer;
  3. JSON response is also intercepted by nginx and processed by MyWebApp.

Does this make any sense, and what would be the nginx config for, say, /fileupload Location to proxy it to SomeServer?


Solution

  • I don't have a server to use to stand in for SomeServer for me to test out my suggestions, but I'll give it a shot anyway. If I'm wrong, then I guess you'll just have to use Flash (sample code from VK).

    How about using an iFrame to upload the file to SomeServer, receive the JSON response, and then use postMessage to pass the JSON response from the iFrame to your main window from your site. As I understand it, that is pretty much the motivation for creating postMessage in the first place.

    Overall, I'm thinking of something like this or YUI's io() module but with postMessage added to get around the same origin policy.

    Or in VK's case, using their explicit iFrame support. It looks to me like you can add a method to the global VK object and then call that method from the VK origin domain using VK.callMethod(). You can use that workaround to create a function that can read the response from the hidden iFrame.

    So you use VK.api('photos.getUploadServer', ...) to get the POST URL.

    Then you use JS to insert that URL as the action for your FORM that you use to upload the file. Follow the example under "Uploading Files in an HTML Form" in the io() docs and in the complete function, use postMessage to post the JSON back to your parent window. See example and docs here. (If it doesn't work with io(), you can certainly make it work using the roll-your-own example code if I'm right about VK.callMethod().)

    Then in response to the postMessage you can use regular AJAX to upload the JSON response back to your server.