Google app engine XMLHttpRequest错误

Google app engine XMLHttpRequest错误,google-app-engine,xmlhttprequest,cors,djangoappengine,django-cors-headers,Google App Engine,Xmlhttprequest,Cors,Djangoappengine,Django Cors Headers,我有一个GoogleAppEngine应用程序,当所有东西都在一台主机上运行时,它在生产中运行良好,而当web应用程序在另一台主机上运行时,它大部分都能正常工作。与服务器之间的所有查询(GET、POST、PUT、DELETE)均按预期运行。这向我表明,我已经在整个系统中正确配置了所有COR(我在几周前打过那场战斗,并且已经解决了所有问题) 我唯一做不到的就是上传文件。我使用的是django,djangoappengine,django cors headers,以及filetransfers,所

我有一个GoogleAppEngine应用程序,当所有东西都在一台主机上运行时,它在生产中运行良好,而当web应用程序在另一台主机上运行时,它大部分都能正常工作。与服务器之间的所有查询(
GET
POST
PUT
DELETE
)均按预期运行。这向我表明,我已经在整个系统中正确配置了所有COR(我在几周前打过那场战斗,并且已经解决了所有问题)

我唯一做不到的就是上传文件。我使用的是
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.
同样,当从同一主机运行时,与此非常相似的代码可以正常运行(因此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的格式是
/\u ah/upload/
,在该URL上发生的一切(似乎)都超出了我的控制范围,包括添加标题。

一种方法是在你的
应用程序中为特定URL设置http标题。yaml

例如:

handlers:
- url: /_ah/upload....
  ...
  http_headers:
    Access-Control-Allow-Origin: http://localhost:9000

http处理程序必须具有将cors头发送到浏览器的方法选项

比如,;Chrome总是在检查CORS头的PUT请求之前向同一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'

此特定设置仅在静态文件处理程序上可用(请参阅)。几天前,当我第一次发现这一点时,我很有希望,但据我所知,这对这种情况并没有帮助。当我说“从同一主机运行时,这是有效的”,我应该澄清一下。post和响应处理的细节有些不同,因为之前的应用程序没有使用AngularJS;可能我在这里做的其他事情也有点错误,但在我解决CORS问题之前,我无法解决任何问题。
url
的处理程序是否发送CORS头?下面是一个让它工作的示例:为什么不直接将formData中的文件发布到端点,而不是先获取然后发布?像
var输入=$('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()
端点url是由数据存储动态创建的,只能使用一次,因此我必须从服务器检索url(GET)然后将要上载的文件发布到该端点。我从来没有找到一个好的解决方案。相反,我在AppEngine项目上创建了一个表单,该表单有两个JavaScript挂钩来表示重要事件(加载、选择文件、上载完成等),然后我将该表单作为IFrame嵌入到客户端应用程序中,并侦听这些事件。虽然很难看,但它完成了任务。这项工作已经完成,并且可以在所有其他端点上工作。在我的代码库之外(由应用引擎环境中的外部服务处理)的单个端点不提供这些头。
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'