最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - JSON string created in Rails replaces whitespace with plus sign (+) - Stack Overflow

programmeradmin0浏览0评论

Rails:

object = Object.find_by(params[:id])

object_items = { "1" => { :id => "123456", :name => "Pancakes Yum!" }, "2" => { :id => "789010", :name => "hello 123" }}

cookies[:something] = { "id" => object.id, "title" => object.title, "object_items" => object_items }.to_json

Let's say that object.title produces a string "Hello World"

Cookie Content:

%7B%22id%22%3A2%2C%22title%22%3A%22Hello+World%22%2C%22object_items%22%3A%7B%221%22%3A%7B%22id%22%3A%22123456%22%2C%22name%22%3A%22Pancakes+Yum!%22%7D%2C%222%22%3A%7B%22id%22%3A%22789010%22%2C%22name%22%3A%22hello+123%22%7D%7D%7D

Problem:

The JSON string being created replaces/escapes whitespace with a plus sign (+) instead of %20 which means that if I were to read the string and grab the value for object.title in HTML/JavaScript it will read it as "Hello+World" and not "Hello World" as expected.

All other characters seem to be replaced/escaped properly - is it because the space exists inside a double quote? I can't figure out why it's producing this string as it is.

Rails:

object = Object.find_by(params[:id])

object_items = { "1" => { :id => "123456", :name => "Pancakes Yum!" }, "2" => { :id => "789010", :name => "hello 123" }}

cookies[:something] = { "id" => object.id, "title" => object.title, "object_items" => object_items }.to_json

Let's say that object.title produces a string "Hello World"

Cookie Content:

%7B%22id%22%3A2%2C%22title%22%3A%22Hello+World%22%2C%22object_items%22%3A%7B%221%22%3A%7B%22id%22%3A%22123456%22%2C%22name%22%3A%22Pancakes+Yum!%22%7D%2C%222%22%3A%7B%22id%22%3A%22789010%22%2C%22name%22%3A%22hello+123%22%7D%7D%7D

Problem:

The JSON string being created replaces/escapes whitespace with a plus sign (+) instead of %20 which means that if I were to read the string and grab the value for object.title in HTML/JavaScript it will read it as "Hello+World" and not "Hello World" as expected.

All other characters seem to be replaced/escaped properly - is it because the space exists inside a double quote? I can't figure out why it's producing this string as it is.

Share Improve this question edited Jan 12, 2012 at 19:11 blake305 2,2365 gold badges24 silver badges52 bronze badges asked Jan 12, 2012 at 18:46 Raymond KaoRaymond Kao 1572 silver badges8 bronze badges 3
  • What if you puts cookies[:something]? Is there a + between Hello and World or is it only present at the client side? – gorootde Commented Jan 12, 2012 at 18:58
  • What URL-encoding parser are you using that doesn't understand that + is a space? – mu is too short Commented Jan 12, 2012 at 19:32
  • mus is too short: it's being parsed by the browser - presumably it's JS engine - in both FF and Chrome in OSX the content value is the same – Raymond Kao Commented Jan 12, 2012 at 20:02
Add a ment  | 

4 Answers 4

Reset to default 3

I don't understand why you are municating with the client via cookies. Why not use a controller action and ajax request?

class SomethingController
  def show
    object = Object.find_by(params[:id])

    object_items = { "1" => { :id => "123456", :name => "Pancakes Yum!" }, "2" => { :id => "789010", :name => "hello 123" }}

    render :json => { "id" => object.id, "title" => object.title, "object_items" => object_items }
  end

Then request it using jQuery or something like this:

$.get('/something/1.json', function(results) { alert(results); });

What's the point in using Rails if you're not going to use Rails?

Cookies are CGI escaped before being sent to the client. When the client retransmits them Rails unescapes them.

You can test the behaviour like this:

rails console c
CGI.escape("something something")
=> "something+something"
CGI.unescape("something+something")
=> "something something"

Since the cookie contents are using CGI.escape in the setter, just pre-escape them with URI.escape, then %20 passes through CGI.escape unchanged, and javascript can unescape %20 back to a space.

cookies[:snickerdoodle] = URI.escape("String With Spaces")

It seems like it is using the old version of percent encoding:

http://en.wikipedia/wiki/Percent-encoding#The_application.2Fx-www-form-urlencoded_type

I had a similar problem and solved changing the cookie after the assignation with a regex replacement:

response.headers['Set-Cookie'].gsub!(/\+/, '%20')
发布评论

评论列表(0)

  1. 暂无评论