Monday, June 3, 2024
 Popular · Latest · Hot · Upcoming
31
rated 0 times [  35] [ 4]  / answers: 1 / hits: 20665  / 10 Years ago, thu, august 21, 2014, 12:00:00

I tried to use jQuery Dropzone to upload an image to Imgur or any other domain but that's not working.



This is my dropzone setup:



$(div.dropzone).dropzone
success: -> console.log arguments
paramName: image
method: post
maxFilesize: 2
url: https://api.imgur.com/3/upload
headers:
Authorization: Client-ID *************


This doesn't work. It says that return code is 0. The request headers:



Host: api.imgur.com
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:31.0) Gecko/20100101 Firefox/31.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Origin: http://my.opencubes.io
Access-Control-Request-Method: POST
Access-Control-Request-Headers: authorization,cache-control,x-requested-with
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache


First as you can see the cient id doesn't appear :(. But the big problem is that the method used is OPTIONS. The response headers:



headers



I have the same problem when I try to upload the file to another domain of mine (the dropzone is located in a subdomain)



In the console I see:



Une demande multi-origines (Cross-Origin Request) a été bloquée : la politique « Same Origin » ne permet pas de consulter la ressource distante située sur https://api.imgur.com/3/upload. Ceci peut être corrigé en déplaçant la ressource sur le même domaine ou en activant CORS.


Which can be translated by




A multi-origin request was blocked: the policy Same origin does not allow to see remote resource located in https://api.imgur.com/3/upload. this an be fixed by moving the resource on the samin domain or by enabling CORS.



More From » cors

 Answers
91

The OPTIONS request is a normal request: this is used to ask for permissions relative to CORS restrictions. Have a look to this page to understand how CORS work under the hood.



In your case, this is a pure CORS related issue. The OPTIONS request contains this header:



Access-Control-Request-Headers: authorization,cache-control,x-requested-with


Which means: can I use authorization, cache-control and x-requested-with headers in my cross-domain AJAX request ?



The response you get is the following:



Access-Control-Allow-Headers :Authorization, Content-Type, Accept, X-Mashape-Authorization


Which means: you're allowed to use those headers only: Authorization, Content-Type, Accept, and X-Mashape-Authorization.



As you can see, cache-control and x-requested-with are not listed in the allowed list, causing the browser to reject the request.



I've come to 2 test code sample which show this behavior:



Example 1 (working)



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');
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 ...):





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)



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');
// the only difference with the previous code is this line
xhr.setRequestHeader('Cache-Control', 'no-cache');
xhr.send(data);


Preflight request's headers:





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.



Here's a JSFiddle referencing different working and not working demos for your problem: http://jsfiddle.net/pomeh/Lfajnebh/. Pay attention to details to understand what's going on, there is few comments but they are here to emphasis trickiest parts of the code.



As a bonus, I've sent a pull request to DropZone's GitHub repository to fix this problem (https://github.com/enyo/dropzone/pull/685) which allows you to remove pref-defined headers by DropZone. Give it a try:



var myDropzone = new Dropzone('.dropzone', {
//...
headers: {
'Authorization': authorizationHeader,
// remove Cache-Control and X-Requested-With
// to be sent along with the request
'Cache-Control': null,
'X-Requested-With': null
}
});


The code above should work with my patched version (https://github.com/pomeh/dropzone/commit/f0063db6e5697888582421865840258dec1ffdc1), whereas the code above should not:



var myDropzone = new Dropzone('.dropzone', {
//...
headers: {
'Authorization': authorizationHeader,
// remove Cache-Control and X-Requested-With
// to be sent along with the request
}
});

[#69701] Tuesday, August 19, 2014, 10 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
malkajillc

Total Points: 652
Total Questions: 107
Total Answers: 98

Location: Finland
Member since Sat, Nov 6, 2021
3 Years ago
malkajillc questions
;