【问题标题】:JSON string created in Rails replaces whitespace with plus sign (+)在 Rails 中创建的 JSON 字符串用加号 (+) 替换空格
【发布时间】:2012-02-09 01:34:54
【问题描述】:

导轨:

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

假设 object.title 产生一个字符串“Hello World”

Cookie 内容:

%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

问题

正在创建的 JSON 字符串用加号 (+) 而不是 %20 替换/转义空格,这意味着如果我要读取字符串并在 HTML/JavaScript 中获取 object.title 的值,它将将其读作“Hello+World”,而不是预期的“Hello World”。

所有其他字符似乎都被正确替换/转义 - 是因为空格存在于双引号内吗?我无法弄清楚为什么它会按原样生成这个字符串。

【问题讨论】:

  • 如果您puts cookies[:something] 会怎样? Hello 和 World 之间是否存在+ 还是仅存在于客户端?
  • 您使用的哪个 URL 编码解析器不理解 + 是一个空格?
  • mus 太短:它正在被浏览器解析 - 可能是 JS 引擎 - 在 OSX 中的 FF 和 Chrome 中,内容值是相同的

标签: javascript ruby-on-rails json cookies whitespace


【解决方案1】:

由于 cookie 内容在 setter 中使用 CGI.escape,只需使用 URI.escape 预先转义它们,然后 %20 不变地通过 CGI.escape,javascript 可以将 %20 转义回空格。

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

【讨论】:

    【解决方案2】:

    我遇到了类似的问题,并在分配后用正则表达式替换解决了更改 cookie:

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

    【讨论】:

      【解决方案3】:

      我不明白您为什么要通过 cookie 与客户端通信。为什么不使用控制器操作和 ajax 请求?

      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
      

      然后使用 jQuery 或类似的东西请求它:

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

      如果你不打算使用 Rails,那么使用 Rails 有什么意义?

      Cookie 在发送到客户端之前经过 CGI 转义。当客户端重新传输它们时,Rails 会取消转义它们。

      您可以像这样测试行为:

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

      【讨论】:

      • 我们需要持久化数据,还不能使用本地存储:(
      【解决方案4】:

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-10-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-06-04
        • 2013-05-09
        相关资源
        最近更新 更多