我有一个谷歌应用引擎应用程序,在所有内容都在一个主机上运行时,它可以很好地在生产环境中工作,并且当Web应用程序在单独的主机上运行时,大部分情况下也可以正常工作。所有与服务器的查询(GET,POST,PUT,DELETE)均按预期进行。这表明我已经在整个系统中正确配置了所有CORS(我几周前就解决了这个问题)。
唯一无法使其正常工作的部分是文件上传。我正在使用django、djangoappengine、django-cors-headers和filetransfers,所有这些的净结果是,当从远程服务器运行时,我无法上传文件,但其他所有东西都能正常工作。在Chrome的JavaScript控制台中,我看到以下错误:
这显然是一个CORS错误,所以我大致知道需要发生什么。但我无法弄清楚如何对我的配置进行必要的更改以克服这个问题。
这是我的总体设置:
- dev_appserver.py在8080端口上提供API服务 - grunt serve在9000端口上提供客户端应用程序 - CORS设置:
- 开发环境:CORS_ORIGIN_ALLOW_ALL = True - 生产环境:CORS_ORIGIN_WHITELIST = [ '(app.domain.com for my app)' ]
在生产环境中,我认为解决方法是配置我的bucket的CORS,但我不确定。然而,在部署之前,我不知道如何为本地开发服务器配置它,以便测试数据的整体流程。
以下是最终失败的JavaScript(该应用程序使用AngularJS):
我得到的URL的格式为
唯一无法使其正常工作的部分是文件上传。我正在使用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在8080端口上提供API服务 - grunt serve在9000端口上提供客户端应用程序 - CORS设置:
- 开发环境:CORS_ORIGIN_ALLOW_ALL = True - 生产环境:CORS_ORIGIN_WHITELIST = [ '(app.domain.com for my app)' ]
在生产环境中,我认为解决方法是配置我的bucket的CORS,但我不确定。然而,在部署之前,我不知道如何为本地开发服务器配置它,以便测试数据的整体流程。
以下是最终失败的JavaScript(该应用程序使用AngularJS):
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
来组装我的上传表单,但我以前从未找到过这样的方法。
--- 更新以添加 ---
澄清一点,导致此错误的端点不是直接在我的应用程序内部,而是在由一个单独的Google服务处理的URL上。给我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/<一次性密钥>
,该URL上发生的所有事情(似乎)都不在我的控制范围之内,包括添加标头。
url
的处理程序是否发送CORS标头?以下是使其正常工作所需执行的示例:https://github.com/GoogleCloudPlatform/appengine-python-blobstore-cors-upload/blob/master/main.py - Josh Jvar input = $('selector'); var data = new FormData(); data.append('name', input.name); data.append('type', input.type); data.append(input.name, input.files[0]); $.ajax({ url: 'url', type: 'POST', processData: false, contentType: false, // important for jqXHR data: data}.done()
- dliu/_ah/upload
在预检测的OPTIONS请求期间失败。 - redhotvengeance