我有一款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