我有一个rails应用程序,它有一个人们可以使用的API。不幸的是,api显然只允许我做GET请求而没有别的。我尝试了一个POST请求,您无需进行身份验证。
所有API控制器都使用从BaseController
扩展的ApplicationController
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
现在核心网址是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我得到:
{{1}}
那么为什么我可以执行GET请求而不是POST请求呢?
答案 0 :(得分:0)
尝试:
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)
}
})
如果您使用反向代理来提供请求,建议使用它,我认为在请求中没有多少负责的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;
}
通过这样做,你不需要在铁轨上做任何事情。
希望这对你有所帮助。
答案 1 :(得分:0)
<强>机架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是一个配置地狱 - 你将更适合使用上述代码和放大器。宝石保持清洁。我们上面的工作非常好
答案 2 :(得分:0)
为了使用主干,您需要进行同步调整,看起来像这样:
(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' })