我遇到了一个非常奇怪的错误。我有一个使用 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 请求。但有时它仍然有效......我不知道如何解决它。为什么它有时会失败?