1

I'm using Sinatra. I've got a button that sends a JSON-formatted string to the server by making a POST request. Only problem is, the JSON string isn't getting to the server.

Here's index.erb:

<input id="post-button" type="button" value="Send POST request">

Here's script.js:

window.onload = function(){
  var btn = document.getElementById('post-button');
  btn.onclick = function(){
    var req = new XMLHttpRequest();
    var reqObj = {
      name: 'Joe',
      age: '100'
    };
    var reqJSON = JSON.stringify(reqObj);

    req.open('POST','/post_target',true);
    req.setRequestHeader('Content-Type', 'application/json;charset=UTF-8');
    req.send(reqJSON);
  }
}

And finally, main.rb:

get '/' do 
    erb :index
end

post '/post_target' do 
    p params
end

When I click the button and check Firebug, I see that the browser sent a POST request. But when I check the Ruby console, it prints {} for params. If it worked right, I guess params would show a JSON object in string form, along with whatever else it would show.

I'm running Sinatra on my machine, at address http://localhost:4567.

What am I doing wrong? If I need to do the request with jQuery, I can do that, but can it be done with "vanilla" JavaScript?

Generic_User_ID
  • 1,067
  • 2
  • 13
  • 16
  • Hmm...could it be because you are setting the request's content-type to JSON but are actually sending a string? What happens when you set the request content-type to application/x-www-form-urlencoded? (Disclaimer: I'm not really sure how Sinatra works - hence posting a comment instead of an answer) – gvk Oct 18 '14 at 00:19
  • Nah, removing the content-type gets the same result when the code runs. – Generic_User_ID Oct 18 '14 at 02:47

3 Answers3

1

"params" is most likely looking for URL encoded query string values. You want the Body content of the post, not the params.

See How to parse JSON request body in Sinatra just once and expose it to all routes?

Community
  • 1
  • 1
Alex Hill
  • 713
  • 1
  • 5
  • 13
1

You need to parse the JSON body:

parsed_params = JSON.parse( request.body.read, symbolize_names:true )
B Seven
  • 44,484
  • 66
  • 240
  • 385
1

Alex Hill is right. And the the post he mentioned show one way to solve it.

An other way is to use rack/contrib:

require it:

require 'rack'
require 'rack/contrib'

add the middleware

use Rack::PostBodyContentTypeParser

source: http://jaywiggins.com/2010/03/using-rack-middleware-to-parse-json/

Sir l33tname
  • 4,026
  • 6
  • 38
  • 49