我有一款Google App Engine應用程序,當一切正在一臺主機上運行時,它可以在生產環境中正常運行,並且大多數情況下可以在Web應用程序在單獨的主機上運行時運行。所有查詢到/從服務器(GET
,POST
,PUT
,DELETE
)的行爲都如預期。這告訴我,我已經在整個系統中正確配置了所有的CORS(我幾周前參加了這場戰鬥,並且全部解決了這個問題)。XMLHttpRequest錯誤
我無法做的唯一工作就是文件上傳。我正在使用django
,djangoappengine
,django-cors-headers
和filetransfers
,而最終的結果是,從遠程服務器運行時無法上載文件,但其他所有內容都正常工作。在Chrome的JavaScript控制檯中,我看到以下錯誤:
XMLHttpRequest cannot load http://localhost:8080/_ah/upload/ahl...<truncated>.
Response to preflight request doesn't pass access control check: No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://localhost:9000' is therefore not allowed
access. The response had HTTP status code 405.
這顯然是一個CORS錯誤,所以我大概知道需要發生什麼。除了我不知道如何對我的配置進行必要的更改以克服此問題。
這是我的總體格局:
dev_appserver.py
服務的API端口8080grunt serve
端口服務的客戶端應用程序9000個- CORS設置:
- 發展:
CORS_ORIGIN_ALLOW_ALL = True
- 生產:
CORS_ORIGIN_WHITELIST = [ '(app.domain.com for my app)' ]
- 發展:
在生產中,我相信的修復將是configure CORS on my bucket,但我還不能肯定。但是,我有沒有的想法如何配置本地開發服務器,以便我可以在部署之前測試整個數據流。
這裏是一個的最終失敗(應用程序正在使用AngularJS
)JavaScript的:
var form = angular.element('#media-form');
var data = new FormData(form);
// have the API return a URL using prepare_upload in
// filetransfers module to upload to:
var uploadActionUrl = https://api.domain.com/upload_url/';
$http.get(uploadActionUrl)
.then(function(response) {
// I get here with no problem
$http.post(response.data.action, formData)
.then(function(response) {
console.log('got:', response);
}, function(error) {
console.log('upload error:', error); // <- this is where I end up
});
}, function(error) {
console.log('get upload URL error:', error);
});
再次,代碼非常喜歡這個功能,正確地從同一主機上運行時(因此API本身運行正常), (重要的是)所有的HTTP方法都可以在除了上傳文件之外的所有端點上工作,所以CORS本身的設置與App Engine的交互是正確的。這只是文件上傳部分不起作用。
它發生在我身上,或許該修復包括使用JSON代替FormData
來組裝我的表單,但我從來沒有找到過這樣做的方法。
---更新,增加了---
作爲澄清一點,這是造成這個錯誤並不直接我的應用程序內的端點,它是由單獨的谷歌服務處理的URL。這給我的網址的代碼是:
from google.appengine.ext.blobstore import create_upload_url
def prepare_upload(request, url, **kwargs):
return create_upload_url(
url,
gs_bucket_name = settings.GOOGLE_CLOUD_STORAGE_BUCKET
), {}
我回來的URL的形式/_ah/upload/<one-time key>
的,而且發生在該URL的一切是(似乎)我的控制範圍之外,包括添加標題。
當我說「在同一主機上運行時,該工作」,我要澄清。由於之前的應用程序並未使用AngularJS,因此發佈和響應處理的細節稍有不同;有可能我在這裏也做了其他一些稍微錯誤的事情,但在解決CORS問題之前,我無法解決任何問題。 – seawolf
'url'的處理程序是否發送CORS頭文件?這裏是你需要做的工作的一個例子:https://github.com/GoogleCloudPlatform/appengine-python-blobstore-cors-upload/blob/master/main.py –
爲什麼不直接POST文件formData到端點,而不是先獲取然後發佈?像'var input = $('selector'); var data = new FormData(); data.append('name',input.name); data.append('type',input.type); data.append(input.name,input.files [0]); $阿賈克斯({ URL: 'URL', 類型: 'POST', 過程數據:假的, 的contentType:假的,//用於jqXHR 數據重要:數據} .done()' – dliu