我有一个Google应用程序,当所有的东西都在一个主机上运行时,它在生产中工作得很好,而当web应用程序在一个单独的主机上运行时,它主要工作。对服务器的所有查询(GET
、POST
、PUT
、DELETE
)都按预期进行。这表明我在整个系统中正确地配置了所有CORS (我几周前就打过这场仗,并且已经解决了这一切)。
我唯一做不到的就是上传文件。我使用的是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
grunt serve
CORS_ORIGIN_ALLOW_ALL = True
CORS_ORIGIN_WHITELIST = [ '(app.domain.com for my app)' ]
在生产中,我相信修复将是在我的桶上配置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本身为与Again的交互而正确设置。只有文件上传部分不能正常工作。
我突然意识到,修复可能包括使用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/<one-time key>
,在该URL上发生的一切(似乎)都超出了我的控制范围,包括添加标题。
发布于 2016-03-04 22:49:03
一种方法是为app.yaml
中的特定url设置http头。
例如:
handlers:
- url: /_ah/upload....
...
http_headers:
Access-Control-Allow-Origin: http://localhost:9000
发布于 2016-03-11 13:49:56
您的http处理程序必须具有将cors头发送到浏览器的选项方法。
例如,Chrome总是在发出检查CORS头的请求之前将选项请求发送到相同的URL。如果浏览器无法获得选项请求的响应,cors将失败。
查看此应用程序引擎webapp2示例。
class BaseRestHandler(webapp2.RequestHandler):
def options(self, *args, **kwargs):
self.response.headers['Access-Control-Allow-Origin'] = '*'
self.response.headers['Access-Control-Allow-Headers'] = 'Origin, X-Requested-With, Content-Type, Accept'
self.response.headers['Access-Control-Allow-Methods'] = 'POST, GET, PUT, DELETE'
https://stackoverflow.com/questions/35805651
复制相似问题