Apache 如何以及为啥拦截对 Rails 的一些 CORS 请求?

Posted

技术标签:

【中文标题】Apache 如何以及为啥拦截对 Rails 的一些 CORS 请求?【英文标题】:How and why is Apache intercepting some CORS requests to Rails?Apache 如何以及为什么拦截对 Rails 的一些 CORS 请求? 【发布时间】:2019-01-04 16:17:33 【问题描述】:

在 Chrome 进行跨域 AJAX 调用之前,它会进行如下所示的 OPTIONS 检查:

curl \
'https://fubar.com/users/sign_in' \
-X OPTIONS \
-H 'Access-Control-Request-Method: POST' \
-H 'Origin: http://snafu.com' \
-H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/67.0.3396.99 Safari/537.36' \
-H 'Access-Control-Request-Headers: content-type' \
--compressed \
--insecure \
--verbose

(我添加了--insecure--verbose进行测试。)

我可以在 Apache 日志中看到这个请求,但它没有到达 Rails。

127.0.0.1 - - [27/Jul/2018:09:22:44 -0400] "OPTIONS /users/sign_in HTTP/1.1" 200 -

如果我删除 Access-Control-Request-MethodOrigin 标头,那么它确实将请求传递给 Rails。

这两个标头的组合似乎导致 Apache 自己处理请求,而不给 Rails 处理它的机会。

我没有在 Apache 配置中设置任何标题或定义任何重写规则;它基本上是一个普通的安装。

我找不到任何文档或配置来解释为什么会发生这种情况以及如何防止它。

【问题讨论】:

为什么是因为规范说以及它是如何在 OPTIONS 响应后终止连接的。 【参考方案1】:

1) OPTIONS'https://fubar.com/users/sign_in' 的 HTTP 调用从 chrome 浏览器执行,请求标头为 'Access-Control-Request-Method: POST''Origin: http://snafu.com'

2)'https://fubar.com/users/sign_in'的服务器收到请求

第 1 步

路由是来自 nginx 或 apache 网络服务器的句柄,它们将首先应用它们自己的配置规则。此设置包含在/etc/apache2/etc/nginx 内的文件中

例如使用 nginx,您可以将规则定义为 add_headerhttp 响应或设置以重定向到另一个 url

例如

add_header "Access-Control-Allow-Origin: '*'"

这会将标题"Access-Control-Allow-Origin: '*'" 添加到所有响应中。 例如,如果您将此响应应用于所有 OPTIONS 请求,则所有后续 http 请求都将从任何 http origin 列入白名单

第 2 步

一旦应用了 nginx/apache 重定向规则,rails router 就会收到请求并重定向到您的控制器。

这里你仍然可以在控制器中添加任何你想要的头,你可以将OPTIONS请求重定向到一个特定的控制器动作,它可以添加一个特定的头,注意不要添加两次相同的头,因为这会导致问题.

在此操作中,您可以重写来自OPTIONS 请求的响应中的Access-Control-Allow-Origin 标头以仅将特定源域列入白名单(您只需编写仅适用于OPTIONS 请求的路由规则)

源域写在请求的头部

请求标头'Access-Control-Request-Method: POST''Origin: http://snafu.com'

【讨论】:

以上是关于Apache 如何以及为啥拦截对 Rails 的一些 CORS 请求?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 rails 对咖啡脚本文件使用 .js.coffee 扩展名,因为它们无论如何都不能包含 JavaScript 代码?

为啥我的 PostgreSQL 数组索引没有被使用(Rails 4)?

为啥 Apache Kafka Streams 使用 RocksDB 以及如何改变它?

为啥所有的 Rails 助手总是对所有视图可用?有没有办法禁用它?

springMVC拦截器中如何获得被拦截方法的返回值

Apache 为 Rails 文件提供错误的 Content-Type