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. :(
class V1::RegistrationsController < ApplicationController
respond_to :json
end
Makes the default reponse format json
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
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