簡體   English   中英

Cors的POST,PUT和PATCH請求不起作用。 只有GET

[英]Cors Requests for POST and PUT and PATCH and so on are not working. Only GET

我有一個Rails應用,該應用具有可供人們使用的API。 不幸的是,該api顯然只允許我執行GET請求,而沒有其他操作。 我嘗試了一個POST請求,您不需要對其進行身份驗證。

ApplicationController擴展BaseController My BaseController被所有API控制器使用。 它看起來像這樣:

module Api
  module V1
    class BaseController < ApplicationController
      respond_to :json
      before_action :default_json
      rescue_from ActiveRecord::RecordNotFound, :with => :record_not_found

      after_filter :cors_access

      protected

      # Give access to everyone from the api sub domain.
      def cors_access
        if request.subdomain == "api"
          headers['Access-Control-Allow-Origin'] = '*'
          headers['Access-Control-Request-Method'] = '*'
        end
      end

    end
  end
end

現在,某些內容的核心網址是api.sitename.com/api/v1/what/x/ever/y

我可以很好地執行GET Request,但是在POST上我得到:

XMLHttpRequest cannot load http://api.writer.aisisplatform.com/api/v1/posts/16/comments/. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:9000' is therefore not allowed access. 

那么,為什么我可以執行GET請求而不執行POST請求?

嘗試:

def cors_access
  if request.subdomain == "api"
    headers['Access-Control-Allow-Origin'] = '*'
    headers['Access-Control-Allow-Methods'] = 'GET, POST, OPTIONS'
    headers['Access-Control-Allow-Credentials'] = 'true'
    headers['Access-Control-Allow-Headers'] = 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type'
  end
end

因此,ajax api的調用將是:

$.ajax('http://api.writer.aisisplatform.com/api/v1/posts/16/comments/', {
    xhrFields: { withCredentials: true },
    crossDomain: true,
    success: function(res) {
        console.log(res)
    },
    error: function (xhr, error) {
        console.log(xhr, error)
    }
})

如果您使用反向代理服務您的請求,建議使用cors它,我認為這不是請求中負責任的rails插入標頭的原因,因此,我將向您展示在nginx中完成的示例:

location /api/ {
    add_header 'Access-Control-Allow-Origin' '*';
    add_header 'Access-Control-Allow-Credentials' 'true';
    add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
    add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';

    proxy_pass http://your_balancer;
}

這樣,您將不需要在導軌中做任何事情。

希望這對您有所幫助。

機架式CORS

強烈建議為此使用rack-CORS gem

#config/application.rb
config.middleware.use Rack::Cors do
    allow do
      origins '*'
      resource 'api/v1', :headers => :any, :methods => [:get, :post, :put, :patch]
    end
end

在控制器中手動使用CORS是一個配置難題-您將更適合使用上述代碼和gem保持其干凈。 我們的上述工作在生產中做得很好

這里有一個很好的Railscast

為了使用主干,您需要同步進行調整,以使外觀看起來像這樣:

(function(Backbone) {
  var methods, _sync;

  _sync = Backbone.sync;

  methods = {
    beforeSend: function() {
      return this.trigger('sync:start', this);
    },
    complete: function() {
      return this.trigger('sync:stop', this);
    }
  };

  Backbone.sync = function(method, entity, options) {
    var sync;

    if (options == null) options = {};

    _.defaults(options, {
      beforeSend: _.bind(methods.beforeSend, entity),
      complete: _.bind(methods.complete, entity)
    });

    // add crossDomain
    if (!options.crossDomain) options.crossDomain = true;

    // add xhrFields
    if (!options.xhrFields) {
      options.xhrFields = {
        withCredentials: true
      };
    }

    sync = _sync(method, entity, options);

    if (!entity._fetch && method === 'read') return entity._fetch = sync;
  };
})(Backbone);

默認情況下,骨干網發出的所有請求的類型都是GET,對於POST,您需要在fetch中發送一個options對象:

model = new Backbone.Model();
model.fetch({ url: 'http://api.com/uri', type: 'POST' })

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM