enyo/dropzone — pull request #685 by pomeh (2014-08-25 23:24:26+00:00)
Title: Allow for removing pre-defined request headers

I'm creating a pull request to correct a CORS-related problem.

Sometimes, we don't want to send those pre-defined headers along with the request. This is really useful when dealing with CORS requests: if we call setRequestHeader("headername", "some value") method, then the preflight OPTIONS request (related to CORS) will have it's header "Access-Control-Request-Headers" referencing the headername header. So, this means for the CORS request to work, the response of the OPTIONS request must have the XX header listed in it's "Access-Control-Allow-Headers". In other words, if we prompt access to "headername" header (via Acces-Control-Request-Headers), then we must be explicitely allowed to use it (via Access-Control-Allow-Headers). And as often with CORS, we might not be able to modify the server response because we're using a third party website, so letting the user the ability to remove it from the initial request is a workaround to do CORS request properly.

The way to remove pre-defined header is to pass a null value as follow:

```javascript
new Dropzone('.dropzone', {
//...
headers: {
"Accept": null,
"Cache-Control": null,
"X-Requested-With": null
}
});
```

Here is two sample code using plain old JavaScript to show the difference when setRequestHeader is called or not.

## Example 1 (working)

```javascript
var data = new FormData();
data.append('image', 'http://placehold.it/300x500');

var xhr = new XMLHttpRequest();
xhr.open('POST', 'https://api.imgur.com/3/upload', true);
xhr.setRequestHeader('Authorization', 'Client-ID xxxxxxxxxx'); // this is relative to imgur API
xhr.send(data);
```

Here are the preflight request's headers sent when running this code (as shown by Firefox 30 devtools, and I've removed unrelated headers such as User-Agent, Accept ...):

> **OPTIONS** https://api.imgur.com/3/upload
Host: api.imgur.com
Origin: http://localhost:8080
Access-Control-Request-Method: **POST**
Access-Control-Request-Headers: **authorization**
Cache-Control: no-cache

And the corresponding response's headers

> access-control-allow-origin :**"*"**
Access-Control-Allow-Methods :"GET, PUT, **POST**, DELETE, OPTIONS"
Access-Control-Allow-Headers :"**Authorization**, Content-Type, Accept, X-Mashape-Authorization"

Here, we can see that we prompt access to the "authorization" header, and the server is accepting this header, allong with the POST method and any origin URL, so the CORS requirements are satisfied and the request is allowed by the browser.

## Example 2 (not working)

```javascript
var data = new FormData();
data.append('image', 'http://placehold.it/300x500');

var xhr = new XMLHttpRequest();
xhr.open('POST', 'https://api.imgur.com/3/upload', true);
xhr.setRequestHeader('Authorization', 'Client-ID xxxxxxxxxx'); // this is relative to imgur API
// the only difference with the previous code is this line
xhr.setRequestHeader('Cache-Control', 'no-cache');
xhr.send(data);
```

Preflight request's headers:

> OPTIONS https://api.imgur.com/3/upload
Host: api.imgur.com
Origin: http://localhost:8080
Access-Control-Request-Method: POST
Access-Control-Request-Headers: authorization,**cache-control**
Cache-Control: no-cache

Preflight response's headers (which is the same as in example 1):

> access-control-allow-origin :"*"
Access-Control-Allow-Methods :"GET, PUT, POST, DELETE, OPTIONS"
Access-Control-Allow-Headers :"Authorization, Content-Type, Accept, X-Mashape-Authorization"

Here, the "Access-Control-Request-Headers" header prompt access for "cache-control", which the server does not provide, so the CORS requirements are **not satisfied* and the request is rejected by the browser.

Those examples don't use dropzone but it behave in the exact same way, you can test it on your own :)

I hope this is clear enough, and it'll help dropzone's users facing CORS related issues.