Запрос Rails JSON не корректно анализируется в параметрах сообщений
Я пытаюсь отладить проблему, когда Rails не расшифровывает данные JSON POST.
Журналы сервера показывают:
2011-12-14T06:44:44+00:00 app[web.2]: Started POST
2011-12-14T06:44:44+00:00 app[web.2]: Processing by PostsController#create as */*
2011-12-14T06:44:44+00:00 app[web.2]: Parameters: {"{\"athlete_id\":\"\",\"known_as\":\"abc\",\"email\":\"[email protected]\",\"result\":\"112233\",\"rx\":false,\"mods\":\"thkjth\",\"notes\":\"\"}"=>nil, "affiliate_id"=>"testaffiliate", "wod_id"=>"12345"}
Обратите внимание, что строка JSON не обрабатывается - Rails назначает ее как ключ в хеше, указывая на значение nil. У кого-нибудь есть идеи до того, как я напишу файл before_filter, который пытается использовать JSON.parse все ключи params?
Я не думаю, что это актуально, поскольку я отправляю и получаю данные в порядке, но эта проблема возникает во время запроса CORS из IE (с использованием XDomainRequest).
Ответы
Ответ 1
before_filter :fix_ie_params, only: [:create, :update]
Для Тонкий:
def fix_ie_params
if request.format == '*/*'
# try to JSON decode in case of IE XDR
begin
params.merge! ActiveSupport::JSON.decode(request.body.string)
rescue Exception=>e
# todo: log exception
end
end
end
Для Единорога и Phusion Passenger:
def fix_ie_params
if request.format == '*/*'
# try to JSON decode in case of IE XDR
begin
request.body.rewind
params.merge! ActiveSupport::JSON.decode(request.body.read)
rescue Exception=>e
# todo: log exception
end
end
end
Ответ 2
Вы можете пройти мимо этого, установив заголовок Content-Type в "application/json". Вы можете позволить контроллеру узнать, что он ожидает, чтобы вернуться с заголовком Accept, установленным в "application/json".
Следующая команда с обоими заголовками:
curl -d '{ "company": { "name": "acme", "address": "123 Carrot Street" } }' http://0.0.0.0:3000/mysite --header "Accept: application/json" --header "Content-Type: application/json"
Создает это в журналах:
Started POST "/mysite" for 127.0.0.1 at 2012-01-11 16:09:48 -0800
Processing by MyController#create as JSON
Parameters: {"company"=>{"name"=>"acme", "address"=>"123 Carrot Street"}, "wassup"=>{"company"=>{"name"=>"acme", "address"=>"123 Carrot Street"}, "controller"=>"wassup", "action"=>"create"}}
Completed 200 OK in 5ms (Views: 2.0ms | ActiveRecord: 0.0ms)
Эта команда с заголовком Accept:
curl -d '{ "company": { "name": "acme", "address": "123 Carrot Street" } }' http://0.0.0.0:3000/mysite --header "Accept: application/json"
Создает эти журналы:
Started POST "/mysite" for 127.0.0.1 at 2012-01-11 16:07:26 -0800
Processing by MyController#create as JSON
Parameters: {"{ \"company\": { \"name\": \"acme\", \"address\": \"123 Carrot Street\" } }"=>nil}
Completed 200 OK in 7ms (Views: 5.0ms | ActiveRecord: 0.0ms)
И, наконец, эта команда с заголовком Content-Type:
curl -d '{ "company": { "name": "acme", "address": "123 Carrot Street" } }' http://0.0.0.0:3000/mysite --header "Content-Type: application/json"
Создает эти журналы:
Started POST "/mysite" for 127.0.0.1 at 2012-01-11 16:08:11 -0800
Processing by MyController#create as */*
Parameters: {"company"=>{"name"=>"acme", "address"=>"123 Carrot Street"}, "wassup"=>{"company"=>{"name"=>"acme", "address"=>"123 Carrot Street"}, "controller"=>"wassup", "action"=>"create"}}
Completed 200 OK in 4ms (Views: 2.0ms | ActiveRecord: 0.0ms)
Обратите внимание, что проанализированные параметры и обрабатывающее сообщение тонко изменяются с каждым типом заголовка.