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 后端架构网站的最佳方式?

《新飞飞》网游服务器架构设计

带有 Spring Security 的 Angular 2 应用程序并从 Spring REST 服务中获取数据

带有查询字符串参数的 Rails 动作缓存

[解读REST] 5.Web的需求 & 推导REST

带有 Vue 和 webpacker 3 的 Rails 5.1 应用程序,未编译 css