Sigh, we're back to this. I can easily enough use CORS on any decent enough browser to directly upload files to my AWS S3 bucket. But (it was coming), with IE I have to fall back to Iframes. Easy, set up a hidden Iframe, create a form, set its target to Iframe name/id, submit form. If the upload is successful, the Iframe is redirected to a url I specify and I can access the whatever I need to. But if an error occurs, since the Iframe is now on an AWS domain, I won't have access to the XML content of the error. Infact, I won't even know that an error has occurred.
I've seen brave people on the internet talking about hosting an html file, on the same bucket to which files are to be uploaded, and then using postMessages to route the Iframe content, or something of that sort.
Could someone please explain to me how to achieve this mythical solution? The jQuery file uploader by Blueimp seems to solve this, but by God the code is so jQueryified that I haven't been able to get the gist of it.
To upload folders and files to an S3 bucketSign in to the AWS Management Console and open the Amazon S3 console at https://console.aws.amazon.com/s3/ . In the Buckets list, choose the name of the bucket that you want to upload your folders or files to. Choose Upload.
For example, the Amazon S3 method PutObject is synchronous, while PutObjectAsync is asynchronous. Like all asynchronous operations, an asynchronous SDK method returns before its main task is finished. For example, the PutObjectAsync method returns before it finishes uploading the file to the Amazon S3 bucket.
While S3 object uploads are atomic, there isn't a guarantee that a folder sync will be.
Almost everything you need to know about how the jQuery File Upload plugin does iframe uploads is in its Iframe Transport plugin (along with supporting result.html page).
As an introduction, you may want to read their user instructions on their Cross domain uploads wiki page, specifically the Cross-site iframe transport uploads section. (Note that according to their Browser support page, niceties like upload progress are not supported for IE <10, so I wouldn't consider these possible using the iframe transport, at least without significant effort.)
(Also, I don't believe any S3 upload implementation using the File Upload plugin has access to the XML content of a file upload error)
The Iframe Transport plugin adds a new Ajax "transport" method for jQuery and is not specific to the File Upload plugin. You may want to read the documentation for jQuery.ajaxTransport() to understand the API that jQuery provides for adding a new transport.
I'll try to summarize what the Iframe Transport plugin is doing, and how it relates to uploading files to Amazon S3:
When a file upload is triggered, the send()
function is called. This function:
Creates a hidden form element
Creates an iframe element with src="javascript:false;"
, and binds a load
event handler to the iframe
Appends the iframe to the hidden form, and appends the hidden form to the document.
When the iframe is created and its "page" loaded, its load
event handler is called. The handler:
Clears itself from the iframe, and binds another load
event handler
Configures the hidden form:
The form's action
will be the URL for the S3 bucket
The form's target
is set to the iframe, so that the server response is loaded in the iframe
Other fields, e.g. AWSAccessKeyId
, are added. Specifically, success_action_redirect
is set to the URL of result.html on your server, e.g. http://example.org/result.html?%s
.
Normally, the %s
token should be replaced with the upload results by server-side code, but with S3 this can be hard-coded with a success value by your code, since Amazon will redirect to this URL only if the upload succeeded.
File input fields from the original form are moved into the hidden form, with cloned fields left in the original fields' place
Submits the hidden form
Moves the file input fields back into the original form, replacing the cloned fields
The file(s) are uploaded to S3. If successful, Amazon redirects the iframe to the success_action_redirect
URL. If not successful, Amazon returns an error, which is also loaded in the iframe.
The iframe's load
event handler is called. The handler:
Tries to save a reference to the iframe's document
object. If the file upload failed, the handler saves an undefined
instead.
Calls the complete callback with a success code and a reference to the iframe's document
object (or undefined
)
Removes the hidden form (and iframe)
Before control is returned to your code, the iframe's document
object is passed to a converter (at the bottom of the Iframe Transport plugin), depending on what type of data you were expecting. The converter extracts that data from the document
object and returns it (or undefined
if the file upload failed) to your callback(s).
Your callback(s) (success
and/or complete
as passed to jQuery.ajax()) is called. A success code is always returned by the plugin, and so any error
callback will not be triggered.
If the data passed to your callback(s) is the value you included in the success_action_redirect
, then the file upload succeeded. If the data is undefined
, then the file upload failed.
Update: If the error XML page stays on the same origin as the S3 bucket, then another page from the S3 bucket, loaded into another iframe, can access the original iframe's content (because they are from the same origin). Your main page can communicate with this second iframe using postMessage()
(or easyXDM's FlashTransport, if you need to support IE6/7).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With