Dropzone: Dropzone CORS issue

Created on 22 Oct 2013  路  18Comments  路  Source: dropzone/dropzone

I'm encountering a problem with dropzone uploading files using CORS, which works when the POST server is the same as the HTML file. The code is below:

   $(form).dropzone({ paramName: "userfile",
                       maxFilesize: 8, // in MB.
               previewsContainer: previewsContainerId,
               withCredentials: true, // For CORS.
                       init: function() {
               this.on("success", function(file, xmlResponse) { 
                // Do all the stuff once the file is uploaded.
               });
                           this.on("sending", function(file, xhr, formData) {
                               console.log("sending " + file);
                   console.log("form " + formData);
                           });
               this.on("error", function(file, errorMessage, xhr) {
                   console.log("Dropzone upload error " + errorMessage + 
                       " sending credentials " + xhr.withCredentials +
                      " ready state: " + xhr.readyState + " status: " + xhr.status);
               });
               this.on("complete", function(file) {
                   this.removeFile(file);
               });
                       }
             });

The results are:

sending [object File]
form [object FormData]
Dropzone upload error Server responded with 0 code. sending credentials true ready state: 4 status: 0

The function containing the call to $(form).dropzone() is called from HTML generated within a PHP file. I am using withCredentials: on other jQuery AJAX calls and the CORS POSTs work fine, yet even with the withCredentials: setting on the dropzone options, or setting it in the "sending" function, it still fails. I'm stumped what the problem is? The only next test I can think of is to try to do jQuery file uploads independent of dropzone.js to see if I can catch what the problem is?

Most helpful comment

Hi. Dropzone does not have a speific CORS header implementation. It's the browsers that don't allow the file being uploaded.
My server sends back those values:

Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:Content-Type, X-Requested-With, X-PINGOTHER, X-File-Name, Cache-Control
Access-Control-Allow-Methods:PUT, POST, GET, OPTIONS
Access-Control-Allow-Origin:http://www.dropzonejs.com

All 18 comments

If you set the forceFallback option, and upload the file normally, does it work?

Great suggestion! Setting forceFallback: presents a Browse button and I can select a file, nothing is uploaded until I press the Submit button in the form, which does indeed trigger an upload (although I don't see the form post in FireBug on FireFox v24) with the correct results being returned. However that upload may not actually be performed by $(form).dropzone() but by the default browser form submission?

Yes @leighsmith , the forceFallback option falls back to the absolute default browser implementation (an file input, and a submit button). It's great to test if the file upload works properly when no JS is involved.

Does your server provide the correct CORS headers?

Yes the server does provide the correct headers, albeit rather than the * wildcard, the specific client server is specified. This is verified by examining the POSTs header with FireBug, and also by other forms being sent by jQuery $.ajax() and received correctly, if the withCredentials: options are set. To clarify, using forceFallback does indeed upload the file to the CORS URL and the correct results are returned, although not via the dropzone() function. I will test if using the wild card origin specification changes behaviour.

I am having the same issue as @leighsmith -- using forceFallback uploads the file to the CORS URL and the correct results are returned, although not via the dropzone() function.

Is there a solution or workaround?

The file never reaches the server?

Hi,
same issue here; with forceFallback:true uploads the file to the CORS server but it does not in without it.
Any news about solution to this problem?
Thanks
Luca
Italy

I'm going to jump in here with a "me too" I have several sub-domains (i.e.: https://bar.foo.com/) that get a lot of data from the main domain (https://foo.com/). I'm wanting to use Dropzone to upload files from https://bar.foo.com/ to https://foo.com/ but I'm stuck and flummoxed.

I have this working properly. Actually, the example on dropzonejs.com works like this. So I suspect that your CORS headers are not correct. It works for normal file uploads because those headers are only for AJAX requests.
Please verify them and reopen the issue if it persists.

Would you mind indicating what the CORS headers are that dropzone.js considers correct? As I mentioned above: "Yes the server does provide the correct headers, albeit rather than the * wildcard, the specific client server is specified." So indicating what headers are being used may help narrow why it doesn't work for us?

Hi. Dropzone does not have a speific CORS header implementation. It's the browsers that don't allow the file being uploaded.
My server sends back those values:

Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:Content-Type, X-Requested-With, X-PINGOTHER, X-File-Name, Cache-Control
Access-Control-Allow-Methods:PUT, POST, GET, OPTIONS
Access-Control-Allow-Origin:http://www.dropzonejs.com

Ok thanks for the headers, can you indicate which browsers you tested against?

IE10, IE11, latest Chrome, FF, Opera, Safari, Konqueror and Chrome Mobile & Safari mobile.

I've created a pull request for this: #685. Can some of you have a look and provide feedback about it ?

in case any one else has this CORS issue..
adding "X-File-Name" as suggested by @enyo into the allowed headers fixed this issue for me.

thanks!

I wanted to test Dropzone.js and I sent all file requests to the very useful requestb.in. I make a quick call in my app to get a test bin (which works using normal AJAX) but when I drop a file it fails to the same destination.

In looking around I'm pretty sure it's down to Dropzone asking for PUT in the allow-methods header. This takes it out of the "simple" mode and forces a pre-flight check which fails because requestd.in doesn't except PUT.

Would it be possible to only ask for PUT in the HTTP header if the user has stated the method to be PUT?

confirmed: X-File-Name helps.
example:

res.setHeader("Access-Control-Allow-Headers", "Authorization, X-Requested-With, Accept, Content-Type, Origin, Cache-Control, X-File-Name");

I am using the react-dropzone-component wrapper and for me, adding Cache-Control and X-Requested-With to the allowed headers did the trick.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

CallMeBruce picture CallMeBruce  路  26Comments

anklos picture anklos  路  15Comments

KateMort picture KateMort  路  22Comments

USvER picture USvER  路  19Comments

dhardtke picture dhardtke  路  15Comments