Rails、REST 架构和 HTML 5:带有飞行前请求的跨域请求
Posted
技术标签:
【中文标题】Rails、REST 架构和 HTML 5:带有飞行前请求的跨域请求【英文标题】:Rails, REST Architecture and HTML 5: Cross domain requests with pre-flight requests 【发布时间】:2011-02-20 23:19:47 【问题描述】:在致力于使我们的网站对 html 5 友好的项目时,我们渴望接受跨域请求的新方法(不再通过隐藏的 iframe 发布!!!)。使用Access Control 规范,我们开始设置一些测试来验证各种浏览器的行为。
当前的 Rails RESTful 架构依赖于四个 HTTP 动词:GET、POST、PUT、DELETE。然而,在访问控制规范中,它规定非简单方法(PUT、DELETE)需要使用 HTTP 动词 OPTIONS 的飞行前请求。此外,在测试过程中,我们发现 Firefox 3.5.8 也存在飞行前 POST 请求。
我的问题是这样的。有人知道 Rails 框架的任何项目致力于解决这个问题吗?如果没有,关于支持 OPTIONS 方法的最佳策略的任何意见,因为它必须支持所有 POST、PUT、DELETE 方法的路由?
【问题讨论】:
【参考方案1】:几天前我发布了一个通过机架中间件实现 CORS 支持的 Gem:
http://github.com/cyu/rack-cors
关于预检 CORS 请求,我无法在 Chrome 中获得预检请求(通过简单的 CORS 请求可以正常工作)。在 Internet 上搜索表明它可能不受支持。我已经在 Chrome 论坛中提出了有关此问题的问题,但尚未收到回复。
【讨论】:
你能举例说明如何在 Rails / Sinatra 中使用它吗?它会进入 config/initializers 吗? 这是我在 Sinatra 中使用它的方式:github.com/cyu/bespin_filesrb/blob/master/files.rb 至于 Rails - 我不确定,我还没有尝试过。不过我会从这里开始:guides.rubyonrails.org/…【参考方案2】:这是来自 Spine js 文档
CORs Rails 集成
让我们创建一个cor方法,它将一些请求访问控制头添加到请求的响应中。
将以下内容添加到 app/application_controller.rb:
before_filter :cor
def cor
headers["Access-Control-Allow-Origin"] = "js-app-origin.com"
headers["Access-Control-Allow-Methods"] = %wGET POST PUT DELETE.join(",")
headers["Access-Control-Allow-Headers"] = %wOrigin Accept Content-Type X-Requested-With X-CSRF-Token.join(",")
head(:ok) if request.request_method == "OPTIONS"
end
虽然 Access-Control-Allow-Origin 使用通配符,但我强烈建议不要使用它,因为它会使您的应用程序受到各种 CSRF 攻击。使用白名单会更好、更安全。
Access-Control-Allow-Headers 部分很重要,尤其是 X-Requested-With 标头。 Rails 不喜欢你向它发送 Ajax 请求时不带此标头,并忽略请求的 Accept 标头,在它实际上应该返回 JSON 时返回 HTML。
值得注意的是,默认情况下,jQuery 不会在跨域请求中添加此标头。这是 Spine 在内部解决的问题,但如果您使用纯 jQuery 处理 COR,则需要手动指定标头。
jQuery.ajaxSetup(
headers: "X-Requested-With": "XMLHttpRequest"
);
某些浏览器首先向服务器发送选项请求,以确保设置了正确的访问标头。您需要在 Rails 中捕捉到这一点,返回 200 状态和正确的标题。为此,请将以下内容添加到应用程序的 config/routes.rb 文件中:
match '*all' => 'application#cor', :constraints => :method => 'OPTIONS'
就是这样,您已经准备好使用 Spine 进行跨域请求了!
【讨论】:
【参考方案3】:我破解了 rails 来支持 options 方法。我在 rails 列表上发布了这个,但它从未超过列表。
GitHub 要点:Rails XHR2 / CORS / OPTIONS support
ctrl+f 查找具有#Options 的行 - 这些是我唯一更改的行。
这里是an example implementation | and another
【讨论】:
以上是关于Rails、REST 架构和 HTML 5:带有飞行前请求的跨域请求的主要内容,如果未能解决你的问题,请参考以下文章
保护 javascript 前端/REST 后端架构网站的最佳方式?