1

我遇到了一个非常奇怪的错误。我有一个使用 sinatra 作为后端的 Angular 应用程序。后端托管在不同的服务器上,所以我在它们之间创建了一个 CORS。我适用于所有 POST、GET 和其他请求。但是当我尝试上传图片时 - 有时(仅有时)我得到“XMLHttpRequest 无法加载http://test-backend.dev/upload/image/。来源http://test-frontend.dev:9003不是Access-Control-Allow-Origin 允许。” 错误。例如,我可以尝试上传同一张图片 5 次。4次会失败,第5次会成功上传。有时它会在第一次上传时没有错误,有时我需要 20 个请求才能通过一个... 大于 600kb 的文件会更频繁地发生错误,而小图像几乎不会发生错误。

这是 Sinatra 后端的一些代码:

configure do
  #To enable cross domain requests
  enable :cross_origin

  set :allow_origin, :any
  set :allow_methods, [:head, :get, :post, :options, :delete, :put]
  set :allow_credentials, true
  set :max_age, "86400"
  set :allow_headers, ['*', 'Content-Type', 'Origin', 'Accept', 'X-Requested-With', 'x-xsrf-token']
  set :expose_headers, ['Content-Type']

  disable :protection
  #set :protection, :origin_whitelist => ['http://localhost:9003/'] #btw, that line doesn't work somehow, so I commented it and disabled all the protection for test purposes

  enable :logging

end

#AngularJS sends option request before any other request. These lines properly manage that
options "/*" do
  headers['Access-Control-Allow-Origin'] = "*"
  headers['Access-Control-Allow-Methods'] = "GET, POST, PUT, DELETE, OPTIONS"
  headers['Access-Control-Allow-Headers'] ="accept, authorization, origin, content-type, X-PINGOTHER"
  "*"
end

#example of always working request
post '/layer/:layer_id' do
  @updated_layer = JSON.parse(request.body.string)
  @layer = PageLayer.where(id: params[:layer_id]).take!

  @updated_layer.each do |k, v|
    @layer[k] = v
  end
  @layer.save
end

#That request gives me error sometimes
post '/upload/image/' do
  #Getting image id from request
  id = params.keys[0]

  @layer = PageLayer.where(id: id).take!
  @layer.original_upload = params[id.to_s]
  @layer.save
  json @layer
end

AngularJS 代码:

#That code to manage $http requests which works fine
lgFrontApp.config ["$httpProvider", ($httpProvider) ->
  $httpProvider.defaults.useXDomain = true
  delete $httpProvider.defaults.headers.common["X-Requested-With"]
]
#And that one is the part of upload plugin: https://github.com/nervgh/angular-file-upload (I also tried to use another one, same error sometimes)    
xhr.open('POST', item.url, true);

angular.forEach(item.headers, function (value, name) {
  xhr.setRequestHeader(name, value);
});

xhr.send(form);

以防万一,sinatra 记录:

#Gets all the POST requests, no eror. But once I've spotted IO error. once.
[Thu Sep 05 2013 10:13:07 GMT+0200 (CEST)] INFO [127.0.0.1] POST lg-angular.dev /upload/image/
[Thu Sep 05 2013 10:13:07 GMT+0200 (CEST)] INFO [127.0.0.1] POST lg-angular.dev /upload/image/
[Thu Sep 05 2013 10:13:07 GMT+0200 (CEST)] INFO [127.0.0.1] POST lg-angular.dev /upload/image/
[Thu Sep 05 2013 10:13:10 GMT+0200 (CEST)] INFO [127.0.0.1] GET lg-angular.dev /uploads/image/lac_app4.jpg
#Another log, No errors as well
[Thu Sep 05 2013 10:13:10 GMT+0200 (CEST)] WARNING 127.0.0.1 - - [05/Sep/2013 10:13:10] "POST /upload/image/ " 200 1863 2.7447

在写这篇文章时,我意识到可能,由于 XMLHttprequest 与 $http 有点不同,它可以发出非 cors 请求。但有时它仍然有效......我不知道如何解决它。为什么它有时会失败?

4

0 回答 0