首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >XMLHttpRequest错误

XMLHttpRequest错误
EN

Stack Overflow用户
提问于 2016-03-04 20:41:30
回答 2查看 1.1K关注 0票数 3

我有一个Google应用程序,当所有的东西都在一个主机上运行时,它在生产中工作得很好,而当web应用程序在一个单独的主机上运行时,它主要工作。对服务器的所有查询(GETPOSTPUTDELETE)都按预期进行。这表明我在整个系统中正确地配置了所有CORS (我几周前就打过这场仗,并且已经解决了这一切)。

我唯一做不到的就是上传文件。我使用的是djangodjangoappenginedjango-cors-headersfiletransfers,这一切的最终结果是当我从远程服务器运行时无法上传文件,但其他一切都正常工作。在Chrome的JavaScript控制台中,我看到了以下错误:

代码语言: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的一个错误,所以我大致知道需要发生什么。但我不知道如何对我的配置进行必要的更改以克服这一点。

以下是我的总体设置:

  • 在端口8080上服务API的dev_appserver.py
  • 在端口9000上服务客户端应用程序的grunt serve
  • CORS设置:
    • 发展:CORS_ORIGIN_ALLOW_ALL = True
    • 生产:CORS_ORIGIN_WHITELIST = [ '(app.domain.com for my app)' ]

在生产中,我相信修复将是在我的桶上配置CORS,但我不是积极的。但是,我不知道如何为此配置本地开发服务器,以便在部署之前测试整个数据流。

以下是最终失败的JavaScript (应用程序正在使用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本身为与Again的交互而正确设置。只有文件上传部分不能正常工作。

我突然意识到,修复可能包括使用JSON而不是FormData来组装我的上传表单,但我过去从未找到过这样做的方法。

--更新为

作为一个澄清点,导致此错误的端点不是直接在我的应用程序中,而是在一个由单独的Google服务处理的URL上。提供URL的代码是:

代码语言:javascript
运行
复制
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上发生的一切(似乎)都超出了我的控制范围,包括添加标题。

EN

回答 2

Stack Overflow用户

发布于 2016-03-04 22:49:03

一种方法是为app.yaml中的特定url设置http头。

例如:

代码语言:javascript
运行
复制
handlers:
- url: /_ah/upload....
  ...
  http_headers:
    Access-Control-Allow-Origin: http://localhost:9000
票数 1
EN

Stack Overflow用户

发布于 2016-03-11 13:49:56

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

例如,Chrome总是在发出检查CORS头的请求之前将选项请求发送到相同的URL。如果浏览器无法获得选项请求的响应,cors将失败。

查看此应用程序引擎webapp2示例。

代码语言:javascript
运行
复制
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'

分享

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35805651

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档