15

Content-Type我实际上正在开发一个使用 Rails 4 的 API 。如果客户端未在标头中指定媒体类型,我想将请求设置为 JSON Content-Type

为了获得这种行为,我尝试before_action在我的中添加以下内容ApplicationController

def set_request_default_content_type
  request.format = :json
end

在我的RegistrationsController#create方法中,我有一个断点来检查一切是否正常。好吧,这个request.format技巧不起作用,尽管该值设置为application/json控制器(或 Rails 内部)似乎不将接收到的请求的 Content-Type 视为 JSON。

我使用以下正文(并且没有 Content-Type)进行了 POST 请求:

{"user" : {"email":"foobar@mail.net","password":"foobarfoo"}}

通过使用 Pry 进行调试,我看到:

 [2] api(#<V1::RegistrationsController>) _  request.format.to_s
 => "application/json"
 [3] api(#<V1::RegistrationsController>) _  params
 => {
       "action" => "create",
   "controller" => "v1/registrations"
 }

这意味着 Rails 没有考虑我的 request.format 配置为 的请求Mime::JSON,而是使用Mime::ALLand 所以它没有解析请求的 JSON 正文。:(

4

6 回答 6

1

您可以在块内定义any类型响应respond_to,这不会限制您的控制器在请求 uri 以 结尾时响应.json,它还可以使您免于显式定义响应类型,并且将保持独立于请求内容类型的响应,如您所愿,例子:

respond_to do |format|
  format.any  {render :json => {foo: 'bar'}}
end
于 2018-02-15T15:34:14.050 回答
1

检查这个SO 答案。它使用constraints如下

defaults format: :json do
  # your v1/registration route here
end
于 2019-12-11T18:44:35.360 回答
0
class V1::RegistrationsController < ApplicationController
  respond_to :json
end

使默认响应格式 json

于 2015-05-11T02:09:33.347 回答
0

您可以在routes.rb文件中使用约束来强制 content_type。

Rails 3 上的示例:

match '/api/endpoint' => 'apis_controller#endpoint', constraints: lambda { |request| request.format = :json }

该行将使Content-Type对该json路由的所有请求成为可能。

在使用and on进行测试时,这个其他解决方案也对我有用:rspec 2.99rspec-rails 2.99rails 3.0.6

params = { username: 'username' }
post '/your_path', params.merge({format: 'json'}).to_json, { 'CONTENT_TYPE' => 'application/json', 'HTTP_ACCEPT' => 'application/json' }
于 2021-12-19T14:19:46.543 回答
0

根据这篇文章,可以创建一些将标头转换为Content-Type: application/json.

# config/application.rb
# ...
require './lib/middleware/consider_all_request_json_middleware'
# ...

module MyApplication
  # ...
  class Application < Rails::Application
    # ...
    config.middleware.insert_before(ActionDispatch::Static, ConsiderAllRequestJsonMiddleware)
    # ...
# lib/middleware/consider_all_request_json_middleware.rb

class ConsiderAllRequestJsonMiddleware
  def initialize(app)
    @app = app
  end

  def call(env)
    env["CONTENT_TYPE"] = "application/json" if env["CONTENT_TYPE"] == "application/x-www-form-urlencoded"

    @app.call(env)
  end
end

我已经用 Rails 6 API-only 项目对其进行了测试,它工作正常。

于 2021-09-30T17:31:58.143 回答
-1

您应该能够使用路由设置默认格式:http: //guides.rubyonrails.org/routing.html#defining-defaults

resources :registrations, ... defaults: { format: 'json' }

另请参阅:如何在 Rails 中设置路由的默认格式? format-for-a-route-in-rails?answertab=active#tab-top


也可能感兴趣:

当它包含“,/”或“/”时,Rails 会忽略接受头,并返回 HTML(如果是 xhr 请求,则返回 JS)。

这是设计为在从浏览器访问时始终返回 HTML。

这不遵循 mime 类型协商规范,但它是绕过带有错误接受标头的旧浏览器的唯一方法。他们让他接受第一个 mime 类型为 image/png 或 text/xml 的标题。

于 2014-04-10T15:39:20.170 回答