opal / opal-browser

Browser support for Opal.
MIT License
115 stars 36 forks source link

`Browser::HTTP.post` stringifies nested hash data #33

Closed jgaskins closed 5 years ago

jgaskins commented 9 years ago

The following code:

data = { post: { body: "hello" } }
Browser::HTTP.post url, data do |request|
  # ...
end

… generates these POST params (inside a Rails app): {"post"=>"{\"body\"=>\"hello\"} (note the inner hash is actually a string). I couldn't figure out how to get this working, so I decided to open an issue. Feel free to let me know if I'm just plain doing it wrong. :-)

meh commented 9 years ago

As far as I know normal POST params cannot be nested, that's why that's what you're seeing.

If you want to send JSON do this:

Browser::HTTP.post url, JSON.dump(data) do |request|
  request.mime_type 'application/json'

  # ...
end
jgaskins commented 9 years ago

Right, you can't technically nest them, but a lot of web apps (I believe all Ruby web frameworks) parse this query string:

post[body]=foo%20bar&post[author]=jamie

… as this:

{
  post: {
    body: "foo bar",
    author: "jamie"
  }
}

The opal-jquery gem posts a nested hash in a format that a Rails app can handle. It appears to serialize it as form data, so I assumed this would do the same. Adding the MIME type puts it into the raw POST data, but that doesn't get handled as params.

jgaskins commented 9 years ago

I apologize, that probably reads unintentionally harsh and entitled. What I mean is, I made assumptions and they were wrong, but I was wondering if there was a way we could make them not wrong. :-)

meh commented 9 years ago

How deep can the nesting go? Is there an RFC or something for that?

jgaskins commented 9 years ago

It looks like it goes arbitrarily deep, either by using opal-jquery's HTTP.post or via curl:

Using opal-jquery's HTTP.post method:

HTTP.post('/null', data: {"foo"=>{"bar"=>{"baz"=>{"quux"=>{"omg"=>{"wtf"=>"lol"}}}}}})

Using curl:

$ curl 'http://localhost:3000/?foo%5Bbar%5D%5Bbaz%5D%5Bquux%5D%5Bomg%5D%5Bwtf%5D=lol'
Started GET "/?foo%5Bbar%5D%5Bbaz%5D%5Bquux%5D%5Bomg%5D%5Bwtf%5D=lol" for ::1 at 2015-03-16 20:26:56 -0400
Processing by HomeController#index as */*
  Parameters: {"foo"=>{"bar"=>{"baz"=>{"quux"=>{"omg"=>{"wtf"=>"lol"}}}}}}

I'll see if I can find an RFC for it.

hmdne commented 5 years ago

This isn't standard as far as I know, but it's a convention. I know that even php follows it. I will be interested in implementing that.

elia commented 5 years ago

@ahmadine that's great, I'll go on and assign this to you 👍