Category Archives: 3.3

Fine Uploader 3.3

Fine Uploader 3.3 has been released, and I have done my best to include some new features and improvements, along with a bunch of bugfixes. The two new major features are CORS support and the ability to delete an uploaded file.

As always, please see the downloads page to download the latest released version of the library.

Known issues

  • If chunking is enabled, and forceMultipart is set to true (and/or paramsInBody is set to true) and you are sending cross-domain upload requests on Safari, the Blob encoded in the request may be empty. This appears to be an issue with Safari, and I have filed a bug report with Apple. (#669)

Features & Enhancements

  • XSS/CORS support for upload and delete file requests. Please read the blog post on this feature for more details. (#621)
  • Allow users to delete uploaded files. Please read the blog post on this feature for more details. (#382)
  • Allow Blob objects to be submitted for uploading via the API. (#552)
  • Set default behavior to include all parameters in the request payload for file uploads. (#604)
  • Allow file sizes to be displayed in FineUploader mode next to the file immediately after they are submitted to the uploader. (#589)
  • Add cancelAll function to API. (#428)
  • Readme re-organized to attempt to improve readability.

Bugs Fixed

  • Don’t URL encode parameters sent in request body. (#676)
  • setParams API call does not apply to the associated file when it is called in an onUploader handler & the browser is IE9 or earlier. (#632)
  • Ensure JSON.parse is used by form uploader to parse responses, if supported. (#629)
  • Update the demo page to indicate that the css & js combined files are version-stamped. (#628)
  • Cookies are saved for chunks even if resume is disabled. (#618)
  • Canceling XHR upload results in error callback invocation. (#608)
  • inputName parameter is included twice in XHR requests. (#595)
  • “Processing…” status message does not appear while waiting for response after sending last byte of last chunk to server. (#584)
  • Logic when handling uploads w/ multiple set to false is flawed. (#581)

Major Features Planned For 3.4

  • Support for uploading directly to Amazon S3. See #582 for more details.
  • Allow immediate upload of pictures taken from a connected camera. See #389 for more details.
  • Allow users to paste to upload images copied from other webpages. See #487 for more details.

Note that the list of planned features may change at any time during the release.

If you have a question or a suggestion, please use the support forums or the issue tracker. Questions or issue reports will not be addressed in the comments section below.

As always, please let me know (in the forums or the issue tracker) if you have any suggestions for improvement, or any killer features you’d like me to add.

-Ray Nicholus

CORS support in 3.3

Updates since the original post/feature implementation

After receiving a number of requests during a relatively short amount of time, I decided to add support for Cross Origin Resource Sharing (CORS). This allows you to send requests to domain A and return the response from some other domain. You will need to enable this new feature if the domain of the server returning responses to Fine Uploader does not match the domain of the origin server. If you don’t know what this means, please do not enable CORS support. Support exists for both upload requests and delete file requests.

Support exceptions

  • CORS requests in IE7 are not supported. In IE8 and IE9, the response from the request iframe is passed to the uploader window via window.postMessage, which is not supported in IE7.
  • Delete file CORS requests in IE9 and earlier are not supported. This is due to the fact that DELETE requests must be preflighted. IE9 and earlier require XDomainRequest to be used when sending CORS requests, and XDomainRequest does not support preflighting. The delete files feature will be automatically disabled in IE9 and earlier if Fine Uploader CORS support is enabled.
var uploader = new qq.FineUploader({
    element: document.getElementById('myUploader'),
    request: {
        endpoint: 'server/upload'
    }
    cors: {
        //all requests are expected to be cross-domain requests
        expected: true,

        //if you want cookies to be sent along with the request
        sendCredentials: true
    }
});

Enabling CORS support

If you set the expected property to true, it is assumed that all requests will be cross-domain requests. If you set expected to true and do not respond using the cross-domain response convention outlined below for non-XHR requests, even if the request is NOT cross-domain, it will be considered a failure.

Handling XHR CORS requests server-side

An incoming upload request was sent via XMLHttpRequest if the request has an X-Requested-With header with a value of “XMLHttpRequest”. If CORS support is enabled in Fine Uploader, you must properly handle the associated requests and format your responses accordingly. Note that, since non-standards headers are sent with all Fine Uploader requests, ALL XHR requests are preflighted. This applies to both delete file requests (which are all XHR requests) and upload requests on browsers that support the File API. This means that you will need to handle an OPTIONS request as well. Your responses must include the appropriate Access-Control headers. If you set the sendCredentials property to true, you should be aware that your responses must NOT include wildcard Access-Control-Allow-Origin headers, and you must also include the Access-Control-Allow-Credentials header. The actual response text for CORS XHR requests will not differ at all from response text for non-CORS requests.

Handling iframe CORS upload requests server-side

An incoming upload request was sent via a form submission inside of a hidden iframe if the request does not have an X-Requested-With header, or if the X-Requested-With header has a value other than “XMLHttpRequest”. Handling cross-domain iframe/form-submit-initiated uploads (in browsers that do not support the File API) is a bit tricky for Fine Uploader. I’ve done my best to make it as simple as possible for developers/integrators, though. Your response for iframe based request (such as required when using IE8 or IE9), will look very similar to your normal response, except it must have a Content-Type header value of “text/html”, and your response must import a helper javascript file via a <script> tag immediately preceding your valid JSON response. For example:

"{\"success\": true, \"uuid\": \"9da17ad5-ad6a-40cd-81b5-226e837db45b\"}<script src=\"http://<YOUR_SERVER_DOMAIN>/iframe.xss.response-<VERSION>.js/"></script>"

All cross-domain iframe-initiated responses must end with the script tag above, and the valid JSON portion MUST include the UUID of the associated file. Note that you must host the iframe.xss.response.js file on an accessible server and reference it in the &ltscript&gt tag accordingly. When the contents of your response is returned to the iframe tracked by Fine Uploader, the associated javascript file imported by the script tag above will be executed, and will pass the JSON portion of your response to the uploader via window.postMessage.

Additional reading on CORS

If you are unfamiliar with handling XHR CORS requests, Mozilla Developer Network has an excellent wiki article on CORS. Please pay attention, in particular, to the sections that describe how to handle preflighted requests, and credentialed requests (if you require credentials to be passed with the cross-domain request and you have set the sendCredentials cors property).

This is my first stab at CORS support in Fine Uploader. So, please let me know if anything can be improved.

-Ray Nicholus

Delete an uploaded file in 3.3

Updates since the original post/feature implementation

Fine Uploader 3.3 has its first new feature: Delete an uploaded file. This has been a highly requested feature, and it’s finally available in 3.3. This feature, if enabled, will allow your users to delete files after they have been uploaded. There are appropriate UI elements for FineUploader mode users (a customizable delete link, status indicators, an optional and customizable confirm dialog) along with a new API function for FineUploaderBasic mode users (and FineUploader mode users), along with a few new callbacks.

Overview

A file is eligible for deletion only after it has been successfully uploaded. In FineUploader mode, if this feature is enabled, a customizable delete link will appear next to the file after it has successfully uploaded.

When the user clicks on this link, first, the onSubmitDelete callback will be invoked. You may return false in your callback handler if you want to abort the request. If not the user will see a (customizable) confirm dialog (if forceConfirm property has been set). If they click “ok” (or if the forceConfirm option has been disabled), a DELETE request will be sent to the server after Fine Uploader invokes the onDelete callback.

A status message, along with a spinner, will appear next to the file while Fine Uploader is waiting for the server response. Once the response is received, Fine Uploader will invoke the onDeleteComplete callback. If the server indicates success in its response, the file will be removed from the UI. If the server indicates failure, a failure status message will be displayed next to the file. If an error has been detected in the response, the onError callback will also be invoked.

In FineUploaderBasic mode, you can order a delete request via the new deleteFile API function. All of the callbacks invoked while in FineUploader mode will also be invoked in FineUploaderBasic mode if you order a delete via this API function.

The Request (and server-side handling)

Fine Uploader sends a separate DELETE request for each file marked for deletion. The UUID of the file is passed as the last item in the request URI. For example, if the UUID of a file, ordered for deletion, is “6a9955d3-8f1e-4c70-ae47-b01b35dd1562”, and the endpoint property specified in the deleteFile option object is “/server/upload” and the domain is http://mysite.com, Fine Uploader will send a DELETE request to the following endpoint:

http://mysite.com/server/upload/6a9955d3-8f1e-4c70-ae47-b01b35dd1562.

The W3C spec specifically states that the resource to be deleted must be part of the URI path, similar to a PUT request.

Note that you can specify custom parameter and additional headers that are sent along with this request. If you specify custom parameters, they will be sent as part of the query string, NOT the request payload. This is due to the fact that many servers will either rip out any request body associated with a DELETE request, or simply throw an error/reject the request. In other words, a DELETE request is much like a GET request.

Note that I have already updated the Java server-side example to handle this new feature, and the PHP file will likely be updated as well before 3.3 releases.

The (Expected) Response

You may return any response you like, as the XMLHttpRequest object will be passed to your onDeleteComplete handler for further examination. However, the response code you return is important to Fine Uploader, as it uses this to determine if the delete has succeeded or not. The following response codes indicate success for this specific request: 200, 202, and 204. Any other response code indicates a failure.

Enabling the Feature

The following is an example of a VERY basic setup that enables you to use the new delete files feature. For more info on the available options, please see the readme.

var uploader = new qq.FineUploader({
    element: document.getElementById('myUploader'),
    request: {
        endpoint: 'server/upload'
    }
    deleteFile: {
        enabled: true,
        forceConfirm: true,
        endpoint: 'server/file'
    }
});

As always, please let me know via the issue tracker or the support forum if you have any ideas that may improve this or any other feature.

-Ray Nicholus