如何将我的序列化 JSON 字符串包装在“单引号”中

Posted

技术标签:

【中文标题】如何将我的序列化 JSON 字符串包装在“单引号”中【英文标题】:How do I wrap my serialized JSON string in 'single quotes' 【发布时间】:2012-10-25 19:25:51 【问题描述】:

我有一个名为blockijavascript 对象,我想使用rest API 对其进行序列化和更新。所以我打电话:

JSON.stringify(blocki)

这给了我这个字符串:

""name":"Updated Blocki","bounds":"x":"2em","y":"2em","w":"8em","h":"12em""

这几乎是我所需要的,除了双引号字符串外面应该有单引号,像这样:

'"name":"Updated Blocki","bounds":"x":"2em","y":"2em","w":"8em","h":"12em"'

根据MDN JSON.stringify 上的示例,它应该返回一个用单引号括起来的字符串。但是当我在该页面中尝试相同的示例时,我得到了用双引号括起来的字符串。例如,当我在 Firefox 和 chrome 控制台中输入 JSON.stringify() 时,我会返回 "" 而不是 ''

如何正确序列化我的 Javascript 对象,使外部引号为:'。同样,这个字符串是我想要实现的一个例子:

'"name":"Updated Blocki","bounds":"x":"2em","y":"2em","w":"8em","h":"12em"'

理想情况下,我想学习一种序列化对象的好方法,而不必在序列化后修改字符串。

编辑: 我认为我需要这样做的原因是,当字符串用双引号括起来时,我正在使用的 API 不知何故不高兴。例如当我这样做时

curl -i -H "Accept: application/json" -H "Content-type: application/json" -X PUT -d ""name":"Updated Blocki","bounds":"x":"2em","y":"2em","w":"8em","h":"12em"" 'http://localhost:3000/api/blockies/17'

请求失败,服务器给出解析错误。但是,当我尝试时:

curl -i -H "Accept: application/json" -H "Content-type: application/json" -X PUT -d '"name":"Updated Blocki","bounds":"x":"2em","y":"2em","w":"8em","h":"12em"' 'http://localhost:3000/api/blockies/17'

put请求成功,对象被更新。

【问题讨论】:

为什么需要包装json字符串?添加引号之类的会使其成为无效的 json 字符串开头。 一个字符串不保留它是用双引号还是单引号声明的信息(假设它被声明了)。就 JavaScript 而言,'"'"\"" 是等价的。 好的我更新了我的帖子为什么我认为单引号和双引号字符串之间存在差异 您不应该以外部引号很重要的方式调用 Curl。如果您正在对 Curl 进行 shell 调用(您没有说明您使用的是哪种语言),您应该(出于安全原因)使用参数作为数组(不带分隔符)而不是作为单个传递的调用字符串。 有人可以回答实际问题吗?就我而言,我需要单引号。 【参考方案1】:

您不需要那些包裹字符串的单引号 - 这些单引号仅在 MDN 页面上显示与输出相对应的 字符串文字

引号不是字符串本身的内容的一部分!

编辑 - 自从我写以上内容以来,您已经编辑了问题。

简单的答案是,如果您绝对必须将字符串用单引号 yourself 括起来,只需使用:

var json = "'" + JSON.stringify(obj) + "'"

更长的答案仍然是您根本不应该包装字符串。将整个命令行传递给 shell 被认为是不好的做法 - 某些环境变量(尤其是 IFS)的存在可能会改变命令行的解释方式,从而导致安全问题。

由于您使用的是 Javascript,我猜您可能正在使用 nodejschild_process 模块?如果是这样,您应该使用.spawn 而不是.exec,并将参数作为数组传递。当以这种方式传递时,参数会直接传递到 Curl 的 argv 数组中,而无需先由 shell 解析,因此根本不需要引用,例如:

var child = spawn('curl', [
    '-i', '-H', 'Accept: application/json',
    '-H', 'Content-type: application/json', 
    '-X', 'PUT',
    '-d', json,
    'http://localhost:3000/api/blockies/17'
]);

或者更好的是直接从 Node 进行 PUT 调用,而不使用 Curl。

【讨论】:

这是一个严厉的反对意见! OP 一开始没有提到“curl”,甚至不应该将包装的字符串参数传递给 shell。【参考方案2】:

用单引号或双引号括起来的字符串之间没有区别,除了由JSON.stringify 方法自动完成的转义。包裹字符串文字的单/双引号不是字符串本身的一部分。

双引号是 Firefox 和 Chrome 更喜欢在控制台中表示字符串文字的方式。


编辑:现在使用 CURL 命令,它完全改变了问题的含义。

""name":"Updated Blocki","bounds":"x":"2em","y":"2em","w":"8em","h":"12em""

上面的字符串不是有效的字符串,因为双引号包裹的字符串中不能有非转义的双引号。

【讨论】:

另外,开发控制台不会在控制台输出转义字符,所以经常看到""foo":"bar"",这在JS源码中实际上是无效的。 是的,@zzzBov 的评论补充了 OP 遇到这种行为的原因,感谢您的补充。 有道理,我更新了我的帖子以说明为什么我认为有区别,你能解释一下为什么第一个 curl 命令失败了吗? @Aras 现在curl 命令完全改变了问题的含义。这取决于您如何将 JS 变量传递给 REST 服务。 那我应该问一个不同的问题吗?【参考方案3】:

周围的单/双引号只是表明它是一个字符串,它不是实际字符串数据的一部分,不能存储。

var serializedData = JSON.stringify("name":"Updated Blocki","bounds":"x":"2em","y":"2em","w":"8em","h":"12em");
var deserializedData = JSON.parse(serializedData);  // whether console displays the serializedData String with single or double quotes is irrelevant

如果您要存储字符串并将其输出到客户端,请用单引号将其包裹起来。

在使用 curl 时,有什么东西会阻止你用单引号括起来吗?

如果你坚持用双引号括起来,你必须像这样转义字符串中的双引号:

"\"name\":\"Updated Blocki\",\"bounds\":\"x\":\"2em\",\"y\":\"2em\",\"w\":\"8em\",\"h\":\"12em\""

【讨论】:

+1 表示转义方法,即使单引号会更简单。【参考方案4】:

例如,当我在 Firefox 和 chrome 中键入 JSON.stringify() 控制台,我返回“”而不是“”。

这就是字符串在控制台中的显示方式。它实际上不是"",而是一个包含 的字符串。引号只是表示它是一个字符串。尝试在 Chrome 控制台中输入“”,您就会明白我的意思了。

【讨论】:

【参考方案5】:

您所看到的只是控制台如何打印字符串的产物。

也就是说,在 Chrome 的控制台中试试这个吧……

JSON.parse(
  JSON.stringify(
    JSON.parse(
      JSON.stringify(
        JSON.parse(
          '"name":"Updated Blocki","bounds":"x":"2em","y":"2em","w":"8em","h":"12em"'
))))).name

【讨论】:

以上是关于如何将我的序列化 JSON 字符串包装在“单引号”中的主要内容,如果未能解决你的问题,请参考以下文章

为啥我不能在 Python 中反序列化带有单引号的 JSON 字符串?

json反序列化的时候字符串为单引号的一个坑

使用 Jackson/Java 来确保 JSON 的所有序列化在单引号或双引号内分隔不受信任的数据会转义任何特殊字符?

如何阻止 Swift 在我的 [String] 中注入转义的单引号?

JSON序列化

在 JSON 编码的 HTML5 数据属性中转义/编码单引号