問題描述
我嘗試使用 jQuery Dropzone 將圖像上傳到 Imgur 或任何其他域,但這不起作用.
I tried to use jQuery Dropzone to upload an image to Imgur or any other domain but that's not working.
這是我的放置區(qū)設(shè)置:
$("div.dropzone").dropzone
success: -> console.log arguments
paramName: "image"
method: "post"
maxFilesize: 2
url: "https://api.imgur.com/3/upload"
headers:
Authorization: "Client-ID *************"
這不起作用.它說返回碼是0.請(qǐng)求標(biāo)頭:
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
首先你可以看到cient id沒有出現(xiàn):(.但最大的問題是使用的方法是OPTIONS
.響應(yīng)頭:
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:
當(dāng)我嘗試將文件上傳到我的另一個(gè)域時(shí)遇到同樣的問題(dropzone 位于子域中)
在我看到的控制臺(tái)中:
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.
可以翻譯的
多源請(qǐng)求被阻止:同源"策略不允許查看位于 https://api.imgur.com/3/upload.這可以通過移動(dòng) samin 域上的資源或啟用 CORS 來解決.
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.
推薦答案
OPTIONS 請(qǐng)求是一個(gè)普通請(qǐng)求:用于請(qǐng)求與 CORS 限制相關(guān)的權(quán)限.查看此頁面了解如何CORS 在后臺(tái)工作.
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.
在您的情況下,這是一個(gè)純粹的 CORS 相關(guān)問題.OPTIONS 請(qǐng)求包含此標(biāo)頭:
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
這意味著:我可以在我的跨域AJAX請(qǐng)求?
Which means: can I use "authorization", "cache-control" and "x-requested-with" headers in my cross-domain AJAX request ?
您得到的響應(yīng)如下:
Access-Control-Allow-Headers :"Authorization, Content-Type, Accept, X-Mashape-Authorization"
這意味著:您只能使用這些標(biāo)頭: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".
如您所見,cache-control"和x-requested-with"未列出在允許列表中,導(dǎo)致瀏覽器拒絕請(qǐng)求.
As you can see, "cache-control" and "x-requested-with" are not listed in the allowed list, causing the browser to reject the request.
我來到了 2 個(gè)顯示這種行為的測試代碼示例:
I've come to 2 test code sample which show this behavior:
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);
以下是運(yùn)行此代碼時(shí)發(fā)送的預(yù)檢請(qǐng)求標(biāo)頭(如 Firefox 30 devtools 所示,我已刪除不相關(guān)的標(biāo)頭,例如 User-Agent、Accept ...):
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 ...):
- 選項(xiàng) https://api.imgur.com/3/upload李>
- 主機(jī):api.imgur.com
- 來源:http://local.host:8080
- 訪問控制請(qǐng)求方法:POST
- Access-Control-Request-Headers:授權(quán)
- 緩存控制:無緩存
以及對(duì)應(yīng)的響應(yīng)頭
- 訪問控制允許來源:*"
- Access-Control-Allow-Methods :"GET, PUT, POST, DELETE, OPTIONS"
- Access-Control-Allow-Headers :"授權(quán)、Content-Type、Accept、X-Mashape-Authorization"
- access-control-allow-origin :"*"
- Access-Control-Allow-Methods :"GET, PUT, POST, DELETE, OPTIONS"
- Access-Control-Allow-Headers :"Authorization, Content-Type, Accept, X-Mashape-Authorization"
在這里,我們可以看到我們提示訪問授權(quán)"頭,并且服務(wù)器正在接受這個(gè)頭,以及POST方法和任何原始URL,因此滿足CORS要求并且請(qǐng)求被允許瀏覽器.
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.
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);
預(yù)檢請(qǐng)求的標(biāo)頭:
- 選項(xiàng)https://api.imgur.com/3/upload
- 主機(jī):api.imgur.com
- 來源:http://local.host:8080
- 訪問控制請(qǐng)求方法:POST
- Access-Control-Request-Headers:授權(quán)、緩存控制
- 緩存控制:無緩存
預(yù)檢響應(yīng)的標(biāo)頭(與示例 1 相同):
Preflight response's headers (which is the same as in example 1):
- 訪問控制允許來源:*"
- 訪問控制允許方法:GET、PUT、POST、DELETE、OPTIONS"
- Access-Control-Allow-Headers :"Authorization, Content-Type, Accept, X-Mashape-Authorization"
這里的Access-Control-Request-Headers"頭提示訪問cache-control",服務(wù)器不提供,所以CORS要求不滿足,請(qǐng)求是被瀏覽器拒絕.
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.
這里有一個(gè) JSFiddle 引用不同的工作和不工作的演示來解決你的問題:http://jsfiddle.net/pomeh/Lfajnebh/一個(gè)>.注意細(xì)節(jié)以了解發(fā)生了什么,評(píng)論很少,但他們在這里強(qiáng)調(diào)代碼中最棘手的部分.
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.
作為獎(jiǎng)勵(lì),我已向 DropZone 的 GitHub 存儲(chǔ)庫發(fā)送了一個(gè)拉取請(qǐng)求以解決此問題(https://github.com/enyo/dropzone/pull/685),它允許您通過 DropZone 刪除預(yù)定義的標(biāo)題.試試看:
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
}
});
上面的代碼應(yīng)該適用于我的補(bǔ)丁版本(https://github.com/pomeh/dropzone/commit/f0063db6e5697888582421865840258dec1ffdc1),而上面的代碼不應(yīng)該:
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
}
});
這篇關(guān)于jQuery Dropzone 的 CORS 問題并上傳到 Imgur的文章就介紹到這了,希望我們推薦的答案對(duì)大家有所幫助,也希望大家多多支持html5模板網(wǎng)!