如何在不退出反斜杠的情况下在Rails中输出JSON
我需要以某种不寻常的格式为客户输出一些JSON。 我的应用程序是用Rails 5编写的。
期望的JSON:
{
"key": "/Date(0000000000000)/"
}
时间戳值需要在字符串的开始和结尾都有一个/
。 据我所知,这似乎是.NET服务中常用的一种格式。 我卡住试图让斜线正确输出。
我通过一个控制器操作将问题简化为了一个vanilla Rails 5应用程序。 迄今为止,我能想到的所有逃生排列都失败了。
def index
render json: {
a: '/Date(0000000000000)/',
b: "/Date(0000000000000)/",
c: '/Date(0000000000000)/',
d: "/Date(0000000000000)/"
}
end
其中输出以下内容:
{
"a": "/Date(0000000000000)/",
"b": "/Date(0000000000000)/",
"c": "/Date(0000000000000)/",
"d": "/Date(0000000000000)/"
}
为了讨论的缘故,假设格式不能被改变,因为它是由第三方控制的。
我上传了一个测试应用程序给Github来展示问题。 https://github.com/gregawoods/test_app_ignore_me
经过与同事的一些头脑风暴(感谢@TheZanke)后,我们找到了一个可以与原生Rails JSON输出结合使用的解决方案。
警告:此代码覆盖ActiveSupport中的一些核心行为。 使用风险自负,并应用适当的单元测试!
我们将其跟踪到ActiveSupport中的JSON编码。 所有字符串最终都通过ActiveSupport::JSON.encode
进行编码。 我们需要找到一种方法来短路该逻辑并简单地返回未编码的字符串。
首先我们扩展了这里找到的EscapedString#to_json
方法。
module EscapedStringExtension
def to_json(*)
if starts_with?('noencode:')
""#{self}"".gsub('noencode:', '')
else
super
end
end
end
module ActiveSupport::JSON::Encoding
class JSONGemEncoder
class EscapedString
prepend EscapedStringExtension
end
end
end
然后在控制器中添加一个noencode:
标志给json散列。 这告诉我们的to_json
版本不要做任何额外的编码。
def index
render json: {
a: '/Date(0000000000000)/',
b: 'noencode:/Date(0000000000000)/',
}
end
渲染输出显示, b
为我们提供了我们想要的东西,而a
保留了标准的行为。
$ curl http://localhost:3000/sales/index.json
{"a":"/Date(0000000000000)/","b":"/Date(0000000000000)/"}
默想这个:
Ruby在双引号和单引号字符串中使用相同的正斜杠。
"/" # => "/"
'/' # => "/"
在双引号字符串"/"
表示正在转义下面的字符。 由于
/
没有转义的等价物,它会导致一个正斜杠:
"/" # => "/"
在所有情况下的单引号字符串中,只有一个意味着存在反斜杠,后跟字符的字面值。 这种情况是你想表示一个反斜杠本身:
'/' # => "/"
"/" # => "/"
'/' # => "/"
学习这是关于在语言中处理字符串最令人困惑的部分之一,这不仅限于Ruby,它是编程早期的事情。
了解以上内容:
require 'json'
puts JSON[{ "key": "/value/" }]
puts JSON[{ "key": '/value/' }]
puts JSON[{ "key": '/value/' }]
# >> {"key":"/value/"}
# >> {"key":"/value/"}
# >> {"key":"/value/"}
你应该能够更好地理解你在结果和上面的JSON输出中看到的内容。
我认为这个规则最初是为C创建的,所以“C中的转义序列”可能会有所帮助。
嗨,我认为这是最简单的方法
.gsub("/",'//').gsub('/','')
用于输入{:key=>"/Date(0000000000000)/"}
(打印)
第一个gsub会做{"key":"//Date(0000000000000)//"}
第二会让你
{"key":"/Date(0000000000000)/"}
如你所需
链接地址: http://www.djcxy.com/p/47929.html上一篇: How to output JSON in Rails without escaping back slashes
下一篇: How to safely embed JSON with </script> in HTML document?