1

私はかなり奇妙なバグに直面しました。バックエンドとしてsinatraを使用するAngularアプリがあります。バックエンドは別のサーバーでホストされているため、それらの間で CORS を作成しました。私はすべての POST、GET、およびその他のリクエストに対して正常に動作します。しかし、画像をアップロードしようとすると、「XMLHttpRequest cannot load http://test-backend.dev/upload/image/ .Origin http://test-frontend.dev:9003 is not Access-Control-Allow-Origin によって許可されています。」エラー。たとえば、同じ画像を 5 回アップロードしようとすることができます。4 回失敗し、5 回目に正常にアップロードされます。最初にエラーなしでアップロードすることもあれば、パス 1 を取得するのに 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