2013-03-17 17 views
16

Kiedy uruchomić polecenia curlJak odczytać dane żądanie POST w szafie

curl -v -H "Content-type: application/json" -X POST -d '{"name":"abc", "id":"12", "subject":"my subject"}' http://localhost:9292 

wysłać żądanie POST z danymi do mojego wniosku do bielizny, moje wydruki kod z {}. To pochodzi z puts req.POST() w poniższym kodzie.

Dlaczego zamiast danych POST wydrukuje się {}? A jak poprawnie uzyskać dostęp do danych POST w aplikacji Rack?

require 'json' 

class Greeter 
    def call(env) 
    req = Rack::Request.new(env) 
    if req.post? 
     puts req.POST() 
    end 
    [200, {"Content-Type" => "application/json"}, [{x:"Hello World!"}.to_json]] 
    end 
end 

run Greeter.new 

Odpowiedz

17

Odczytywanie dokumentów dla POST wygląda tak, jakby zawierało analizowane dane na podstawie innych typów zawartości. Jeśli chcesz przetwarzać "application/json", prawdopodobnie trzeba

JSON.parse(req.body.read) 

zamiast. Aby to sprawdzić, spróbuj

puts req.body.read 

gdzie masz aktualnie puts req.POST.


req.body to obiekt I/O, a nie ciąg. Zobacz dokumentację body i zobacz źródło. Widać, że jest to tak samo jak odpowiedź mudasobwy.

Należy zauważyć, że inny kod w aplikacji Rack może oczekiwać odczytania tego samego wejścia/wyjścia, takiego jak paramery w Sinatrze lub Railsach. Aby upewnić się, że widzą te same dane i nie otrzymają błędu, możesz zadzwonić pod numer req.body.rewind, prawdopodobnie zarówno przed odczytem treści żądania w kodzie, jak i po jej przeczytaniu. Jednakże, jeśli jesteś w takiej sytuacji, możesz zamiast tego zastanowić się, czy twój framework ma opcje przetwarzania JSON bezpośrednio przez jakąś opcję na kontrolerze, czy zażądać deklaracji tresera treści itp. - najprawdopodobniej będzie opcja obsługi tego typu wniosek w ramach.

+1

FYI - Odczyt strumienia I/O z middleware może przerwać aplikację Rails. Kiedy masz wartość, musisz upewnić się, że uruchom 'req.env ['rack.input']. Rewind', aby zresetować strumień. – lookitsatravis

+0

@lookitsatravis: Dzięki, dodałem notatkę o tym do odpowiedzi. OP używa Rack bezpośrednio bez Railsów lub innych frameworków, więc nie będzie miał zastosowania w ich przypadku. Jeśli używasz Railsów, będą inne sposoby na odczytanie żądań 'application/json'. –

+0

@Niel: Zgoda! W moim przypadku użycia, używam [rack-attack] (https://github.com/kickstarter/rack-attack) i jedna z moich kontroli przepustnicy logowania wymaga, że ​​parsuję treść żądania, zanim Rails go odczyta. Przypadek Edge, na pewno, ale to doprowadziło mnie do tego posta i do mojego komentarza. Twoje zdrowie! – lookitsatravis

8

Spróbuj:

env['rack.input'].read 

Znalazłem go w "How to receive a JSON object with Rack", a mimo to wciąż brzmi dziwnie mi się prawdopodobne prace.

+2

fyi, 'gets' przeczyta tylko pierwszą linię –

+4

Nie tylko odczyta tylko pierwszą linę, lecz także separator (domyślnie' \ n') do strumienia. Spowoduje to przerwanie operacji takich jak parsowanie JSON i podpisywanie żądań. Znacznie lepiej jest zrobić "env ['rack.input']." Read' – ianks

3

Można spróbować:

req.params 

Nadzieja to może pomóc.