为啥 Rails 无法识别请求标头中的 `Accept: application/json`?
Posted
技术标签:
【中文标题】为啥 Rails 无法识别请求标头中的 `Accept: application/json`?【英文标题】:Why does rails not recognize `Accept: application/json` in the request header?为什么 Rails 无法识别请求标头中的 `Accept: application/json`? 【发布时间】:2020-01-21 02:34:03 【问题描述】:我有一些前端 javascript 向我的后端 rails 服务器发出异步 http 请求。在前端,我 不 使用 XHR(我使用 axios
,尽管这与问题并不完全相关)。
在请求中,我设置了以下内容来告诉服务器我正在发送 JSON 并确保我返回 JSON:
const config =
headers:
"Content-Type": "application/json",
"Accept": "application/json"
;
在我的后端 Rails 控制器中,如果检查请求,我可以验证 Accept
标头:
> request.headers
"HTTP_ACCEPT"=>"application/json, text/plain, */*"
但是 ActionPack/Rails 仍然不尊重这一点,默认为 format
为 :html
> request.format
=> #<Mime::Type:0x00007fe223919f80 @hash=-1773238723920954657, @string="text/html", @symbol=:html, @synonyms=["application/xhtml+xml"]>
为什么会这样?
我知道我可以将 .json
附加到我的请求 URL 以“强制”它指定该格式,但这是唯一的选择吗?我可以很容易地附加它,但它似乎是特定于 Rails 的实现,而不是真正的“正确”方法。
此外,source code for the request.format
method 明确将:json
设置为 XHR 请求的格式 - Rails 目前是否只尊重 XHR 请求?
谢谢!
【问题讨论】:
【参考方案1】:您所做的是正确的,但是从浏览器发送 Axios/Fetch API 请求会从浏览器端显示“CORS”错误(您可以在浏览器开发工具控制台中看到它)。您可以通过MDN Docs了解更多信息
要解决此问题,您需要将Access-Control-Allow-Origin
标头发送到您在网络服务器上收到的请求。您可以通过在application_controller.rb
中添加此标头来手动执行此操作,或者只需使用像rack-cors
这样的gem。我将向您展示如何使用rack-cors
gem:
Gemfile
中添加gem 'rack-cors'
运行命令bundle i
在您的 config/application.rb
文件中,添加以下行:
config.middleware.insert_before 0, Rack::Cors do
allow do
origins '*'
resource '*', headers: :any, methods: [:get, :post, :options]
end
end
现在重新启动您的 Rails 服务器
您还可以查看以上说明和更多详细信息here现在再次进行 API 调用,不要在 URL 末尾强制使用 .json
,它应该可以工作。
【讨论】:
我最近发现了一篇关于 CORS 的好文章 - dev.to/miguelmota/… 感谢您的解释!但我的请求不是跨域的。我的前端和后端在同一个域下。 你能更新你的axios请求的代码吗?您在控制台中看到任何错误吗?rails server
日志中有任何具体内容吗?
我刚刚在一个测试应用程序中进行了测试 - react + rails(一个应用程序),我使用了 Fetch API,它工作正常。以上是关于为啥 Rails 无法识别请求标头中的 `Accept: application/json`?的主要内容,如果未能解决你的问题,请参考以下文章
无法从获取请求中获取“Access-Control-Allow-Origin”标头
来自 IE 或 Firefox 的 CORS 请求中没有 Referer 标头
为啥 JWT 需要作为 Bearer Token 标头发送?
即使设置了标头,也无法验证 CSRF 令牌的真实性 Rails 4 Ajax