我只是尝试将JSON内容类型的http请求从一个Rails服务器发布到另一个服务器。在JSON中的值字符串中放置%
字符会导致接收服务器上的Rack::QueryParser::InvalidParameterError
。
在服务器A上,我使用httparty gem来执行带有JSON正文的POST请求
obj = {"key":"<%= @results %>"}
resp = HTTParty.post('https://test-url.com/data',
:body => obj.to_json,
:options => { :headers => { 'Content-Type' => 'application/json', 'Accept' => 'application/json' } })
在服务器B上,我只是解析请求正文中的JSON
req_body = request.body.read()
req_body_json = JSON.parse req_body
# do work with json
此过程正常,除非obj = {"key":"<%= @results %>"}
包含%
个字符,在这种情况下,这会发生在服务器B上:
Started POST "/data" for 10.244.1.3 at 2018-01-02 19:27:04 +0000
F, [2018-01-02T19:27:04.245275 #1] FATAL -- :
F, [2018-01-02T19:27:04.245331 #1] FATAL -- : Rack::QueryParser::InvalidParameterError (invalid %-encoding ({"key":"\u003c%)):
F, [2018-01-02T19:27:04.245358 #1] FATAL -- :
F, [2018-01-02T19:27:04.245397 #1] FATAL -- : rack (2.0.3) lib/rack/query_parser.rb:72:in `rescue in parse_nested_query'
rack (2.0.3) lib/rack/query_parser.rb:60:in `parse_nested_query'
rack (2.0.3) lib/rack/request.rb:468:in `parse_query'
rack (2.0.3) lib/rack/request.rb:343:in `POST'
actionpack (5.1.4) lib/action_dispatch/http/request.rb:362:in `block (2 levels) in POST'
actionpack (5.1.4) lib/action_dispatch/http/parameters.rb:107:in `block in parse_formatted_parameters'
actionpack (5.1.4) lib/action_dispatch/http/parameters.rb:107:in `fetch'
actionpack (5.1.4) lib/action_dispatch/http/parameters.rb:107:in `parse_formatted_parameters'
actionpack (5.1.4) lib/action_dispatch/http/request.rb:361:in `block in POST'
rack (2.0.3) lib/rack/request.rb:57:in `fetch'
rack (2.0.3) lib/rack/request.rb:57:in `fetch_header'
actionpack (5.1.4) lib/action_dispatch/http/request.rb:360:in `POST'
...
当我将obj = {"key":"<%= @results %>"}
更改为obj = {"key":"<= @results>"}
时,不会发生异常。
据我所知,%
在JSON中是有效的,我在这里缺少什么?
答案 0 :(得分:0)
考虑他们在这里实施的方式:https://github.com/jnunemaker/httparty/blob/38125db0d079d52a3b0da815150fa2135bb0110d/lib/httparty.rb#L559,
您的body
和headers
哈希键应该是兄弟姐妹,请尝试下一个:
resp = HTTParty.post('https://test-url.com/data',
:body => obj.to_json,
:headers => { 'Content-Type' => 'application/json',
'Accept' => 'application/json' }
)