Force all received requests Content-Type to JSON

北战南征 提交于 2019-12-05 13:40:41

问题


I'm actually working on an API which uses Rails 4. I would like to set the Content-Type of a request to JSON if the client does not specify a media type in Content-Type header.

In order to get that behaviour I tried to add the following before_action in my ApplicationController :

def set_request_default_content_type
  request.format = :json
end

In my RegistrationsController#create method I have a breakpoint to check if everything is working. Well, the request.format trick does not work, despite the value is set to application/json it seems that the controller (or Rails internals) do not consider the received request's Content-Type as JSON.

I did a POST request with the following body (and no Content-Type) :

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

By debugging with Pry I see that :

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

It means that Rails did not have considered my request with the request.format configured with Mime::JSON, but instead with Mime::ALL and so it didn't parse the request's JSON body. :(


回答1:


class V1::RegistrationsController < ApplicationController
  respond_to :json
end

Makes the default reponse format json




回答2:


You could define a any type response inside the respond_to block, which will not restrict your controller to respond when request uri ends with .json, it also relief you from defining a response type explicitly and will keep, independently of request content-type, responding as you wish, example:

respond_to do |format|
  format.any  {render :json => {foo: 'bar'}}
end



回答3:


you should be able to set the default format using routes: http://guides.rubyonrails.org/routing.html#defining-defaults

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

see also: How to set the default format for a route in Rails? format-for-a-route-in-rails?answertab=active#tab-top


Also maybe of interest:

  • http://apidock.com/rails/ActionController/MimeResponds/respond_with
  • http://apidock.com/rails/ActionController/MimeResponds/respond_to (interesting comment at the bottom of this page)

Rails ignores the accept header when it contains “,/” or “/,” and returns HTML (or JS if it’s a xhr request).

This is by design to always return HTML when being accessed from a browser.

This doesn’t follow the mime type negotiation specification but it was the only way to circumvent old browsers with bugged accept header. They had he accept header with the first mime type as image/png or text/xml.



来源:https://stackoverflow.com/questions/22989389/force-all-received-requests-content-type-to-json

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!