将对象字符串转换为 JSON

Posted

技术标签:

【中文标题】将对象字符串转换为 JSON【英文标题】:Convert object string to JSON 【发布时间】:2012-02-20 15:03:16 【问题描述】:

如何使用 javascript(或 jQuery)将描述对象的字符串转换为 JSON 字符串?

例如:转换这个(不是一个有效的 JSON 字符串):

var str = " hello: 'world', places: ['Africa', 'America', 'Asia', 'Australia'] "

进入这个:

str = ' "hello": "world", "places": ["Africa", "America", "Asia", "Australia"] '

如果可能,我希望避免使用eval()

【问题讨论】:

为什么你的字符串首先不是有效的 JSON?你是怎么产生的? 字符串存储在data-attrubute 中,如下所示:<div data-object="hello:'world'"></div> 我不想在 html 中使用单引号(因此它可能不可信) @snorpey: <div data-object='"hello":"world"'></div> 是 100% 有效的 HTML(单引号与信任与否有什么关系?)。如果你这样做,你可以JSON.parse它,它会正常工作。 注意:键也需要引用。 @Rocket 感谢您的努力!我只是想找到一种方法来避免在 HTML 中使用单引号(即使它是 100% 有效)和 JSON 表示法。 @snorpey:他们的方法是首先不将 JSON 放在 HTML 属性中。我猜你可以使用双引号,并转义 JSON <div data-object="\"hello\":\"world\""></div> 中的双引号。如果您不想在属性中使用有效的 JSON,那么您将不得不制作自己的格式并自己解析。 【参考方案1】:

这也可以

let str = " hello: 'world', places: ['Africa', 'America', 'Asia', 'Australia'] "
let json = JSON.stringify(eval("("+ str +")"));

【讨论】:

【参考方案2】:

我希望这个小函数可以将无效的 JSON 字符串转换为有效的字符串。

function JSONize(str) 
  return str
    // wrap keys without quote with valid double quote
    .replace(/([\$\w]+)\s*:/g, function(_, $1)return '"'+$1+'":')    
    // replacing single quote wrapped ones to double quote 
    .replace(/'([^']+)'/g, function(_, $1)return '"'+$1+'"')         

结果

let invalidJSON = " hello: 'world',foo:1,  bar  : '2', foo1: 1, _bar : 2, $2: 3, 'xxx': 5, \"fuz\": 4, places: ['Africa', 'America', 'Asia', 'Australia'] "
JSON.parse(invalidJSON) 
//Result: Uncaught SyntaxError: Unexpected token h VM1058:2
JSON.parse(JSONize(invalidJSON)) 
//Result: Object hello: "world", foo: 1, bar: "2", foo1: 1, _bar: 2…

【讨论】:

我们正在尝试使用 JSON.parse 我们的代码对 b 进行反评估,这看起来是一个不错的解决方案。我们仍然需要手动处理不断的替换,但至少这允许包含这些情况。 几乎完美。当: 处于其中一个值时不起作用。 eval 是纯粹的邪恶,我认为这是要走的路 绝对的天才【参考方案3】:

使用 new Function() 优于 eval,但仍应仅用于安全输入。

const parseJSON = obj => Function('"use strict";return (' + obj + ')')();

console.log(parseJSON("a:(4-1), b:function(), c:new Date()"))
// outputs: Object  a: 3, b: b(), c: Date 2019-06-05T09:55:11.777Z 

来源: MDN, 2ality

【讨论】:

【参考方案4】:
var str = " hello: 'world', places: ['Africa', 'America', 'Asia', 'Australia'] ";
var json = JSON.stringify(eval("(" + str + ")"));

【讨论】:

【参考方案5】:

您最好和最安全的选择是JSON5 – JSON for Humans。它是专门为该用例创建的。

const result = JSON5.parse(" hello: 'world', places: ['Africa', 'America', 'Asia', 'Australia'] ");

console.log(JSON.stringify(result));
<script src="https://cdnjs.cloudflare.com/ajax/libs/json5/0.5.1/json5.min.js"></script>

【讨论】:

【参考方案6】:

您需要使用“eval”然后 JSON.stringify 然后 JSON.parse 到结果。

 var errorString= " hello: 'world', places: ['Africa', 'America', 'Asia', 'Australia'] ";
 var jsonValidString = JSON.stringify(eval("(" + errorString+ ")"));
 var JSONObj=JSON.parse(jsonValidString);

【讨论】:

【参考方案7】:

也许你必须试试这个:

str = jQuery.parseJSON(str)

【讨论】:

问题指定为“或 jQuery”,如果你有它,这是完美的解决方案。【参考方案8】:

使用一个正则表达式而不使用 eval 的解决方案:

str.replace(/([\s\S]*?)(')(.+?)(')([\s\S]*?)/g, "$1\"$3\"$5")

我相信这应该适用于多行和所有可能出现的单引号“字符串”(/g 标志)替换为双引号“字符串”。

【讨论】:

【参考方案9】:

var str = " hello: 'world', places: ['Africa', 'America', 'Asia', 'Australia'] " var fStr = str .replace(/([A-z]*)(:)/g, '"$1":') .replace(/'/g, "\"")

console.log(JSON.parse(fStr))

对不起,我在用手机,这是一张照片。

【讨论】:

【参考方案10】:

只是为了它的怪癖,你可以通过babel-standalone转换你的字符串

var str = " hello: 'world', places: ['Africa', 'America', 'Asia', 'Australia'] ";

function toJSON() 
  return 
    visitor: 
      Identifier(path) 
        path.node.name = '"' + path.node.name + '"'
      ,
      StringLiteral(path) 
        delete path.node.extra
      
    
  

Babel.registerPlugin('toJSON', toJSON);
var parsed = Babel.transform('(' + str + ')', 
  plugins: ['toJSON']
);
var json = parsed.code.slice(1, -2)
console.log(JSON.parse(json))
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>

【讨论】:

【参考方案11】:

对于上面的简单示例,您可以使用 2 个简单的正则表达式替换来做到这一点:

var str = " hello: 'world', places: ['Africa', 'America', 'Asia', 'Australia'] ";
str.replace(/(\w+):/g, '"$1":').replace(/'/g, '"');
 => ' "hello": "world", "places": ["Africa", "America", "Asia", "Australia"] '

大警告:这种天真的方法假定对象没有包含': 字符的字符串。例如,我想不出不使用eval 将以下对象字符串转换为 JSON 的好方法:

" hello: 'world', places: [\"America: The Progressive's Nightmare\"] "

【讨论】:

【参考方案12】:

使用下面链接中的简单代码:

http://msdn.microsoft.com/es-es/library/ie/cc836466%28v=vs.94%29.aspx

var jsontext = '"firstname":"Jesper","surname":"Aaberg","phone":["555-0100","555-0120"]';
var contact = JSON.parse(jsontext);

倒转

var str = JSON.stringify(arr);

【讨论】:

为了类型安全,通过 new String(jsontext) 将 jsontext 转换为 String 对象可能会更好。 @fuzzyanalysis:不,不应该使用原始包装器。 JSON.parse() 应该是@LouiseMcMahon 所述的可接受的答案【参考方案13】:

有一个更简单的方法来完成这个壮举,只需劫持一个虚拟元素的 onclick 属性以强制将您的字符串作为 JavaScript 对象返回:

var jsonify = (function(div)
  return function(json)
    div.setAttribute('onclick', 'this.__json__ = ' + json);
    div.click();
    return div.__json__;
  
)(document.createElement('div'));

// Let's say you had a string like ' one: 1 ' (malformed, a key without quotes)
// jsonify(' one: 1 ') will output a good ol' JS object ;)

这是一个演示: http://codepen.io/csuwldcat/pen/dfzsu(打开你的控制台)

【讨论】:

【参考方案14】:

我把我的答案献给对这个旧线程感兴趣的人。

我为 jQuery 插件创建了 HTML5 data-* parser 和 demo,它们在不使用 eval() 的情况下将格式错误的 JSON 字符串转换为 JavaScript 对象。

它可以传递HTML5 data-* 属性如下:

<div data-object='"hello":"world"'></div>
<div data-object="hello:'world'"></div>
<div data-object="hello:world"></div>

进入对象:


    hello: "world"

【讨论】:

【参考方案15】:

谨慎使用(因为eval()):

function strToJson(str) 
  eval("var x = " + str + ";");
  return JSON.stringify(x);

调用为:

var str = " hello: 'world', places: ['Africa', 'America', 'Asia', 'Australia'] ";
alert( strToJson(str) );

【讨论】:

致匿名的反对者。我挑战你提供更好的解决方案。除此之外,否决票的理由会很好。 @Rocket:你错了。 a)eval() 是唯一的方法。 b)我警告过OP。 c) 查看 Matthew Crumley 的回答并想出一个更好的解释。 (哦,还有 d)声明 eval() is bad 在这种广义形式中是无稽之谈。) @Rocket:啊,误会了。抱歉,我以为反对票是你的。 :) @kuboslav:它工作正常,你测试过吗?他正在做eval("var x = " + str + ";"),这是完全有效的 JS。你不需要做var x = (a:12) @kuboslav 它在 IE7 中不起作用,因为 IE7 没有原生 JSON 支持。只要您使用json2.js,它就会开始工作。不要那么高兴。【参考方案16】:

如果字符串来自受信任的来源,您可以使用eval 然后JSON.stringify 结果。像这样:

var str = " hello: 'world', places: ['Africa', 'America', 'Asia', 'Australia'] ";
var json = JSON.stringify(eval("(" + str + ")"));

请注意,当您eval 一个对象字面量时,它必须用括号括起来,否则大括号将被解析为块而不是对象。

我也同意 cmets 提出的问题,即最好只用有效的 JSON 编码对象,然后避免解析、编码,然后大概再解析它再次。 HTML 支持单引号属性(只需确保对字符串中的任何单引号进行 HTML 编码)。

【讨论】:

这没有意义,如果字符串来自受信任的来源,为什么我们将其转换为有效的 json。 @allenhwkim 想法是将无效的 JSON 转换为有效的 JSON,因此 eval 将字符串转换为 JavaScript 对象(只要字符串表示有效的 JavaScript,即使它不是有效的 JSON)。然后JSON.stringify 从一个对象转换回一个(有效的)JSON 字符串。如果字符串不是来自受信任的来源,则调用 eval 是危险的,因为它实际上可以运行任何 JavaScript,这会打开跨站点脚本攻击的可能性。 在这种情况下,如果构造字符串,eval 仍然会做坏事,例如,像这样: var str = "(function() console.log(\"bad\")) ()"; 使用 eval() 将执行 JS 代码。它很容易被滥用。 @allenhwkim:我们从不信任任何来源。对 IT 的信任意味着检查、检查和再检查。【参考方案17】:

您的字符串不是有效的 JSON,因此 JSON.parse(或 jQuery 的 $.parseJSON)将不起作用。

一种方法是使用eval“解析”“无效”JSON,然后使用stringify将其“转换”为有效JSON。

var str = " hello: 'world', places: ['Africa', 'America', 'Asia', 'Australia'] "
str = JSON.stringify(eval('('+str+')'));

我建议不要尝试“修复”无效的 JSON,而是首先从有效的 JSON 开始。 str 是如何生成的,应该在生成之前修复,而不是生成之后。

编辑:您说(在 cmets 中)此字符串存储在数据属性中:

<div data-object="hello:'world'"></div>

我建议你在这里修复它,所以它可以是JSON.parsed。首先,它们的键和值都需要用双引号引起来。它应该看起来像(HTML 中的单引号属性有效):

<div data-object='"hello":"world"'></div>

现在,您可以使用 JSON.parse(或 jQuery 的 $.parseJSON)。

var str = '"hello":"world"';
var obj = JSON.parse(str);

【讨论】:

【参考方案18】:

您必须编写圆括号,因为没有它们eval 会将大括号内的代码视为命令块。

var i = eval("( hello: 'world', places: ['Africa', 'America', 'Asia', 'Australia'] )");

【讨论】:

【参考方案19】:

免责声明:不要在家里尝试这个,或者任何需要其他开发者认真对待的事情:

JSON.stringify(eval('(' + str + ')'));

在那里,我做到了。 尽量不要这样做, eval 对你不利。如上所述,为旧版浏览器(IE7 及以下)使用 Crockford 的 JSON shim

此方法要求您的字符串是有效的javascript,它将被转换为一个 javascript 对象,然后可以序列化为 JSON。

编辑: 按照 Rocket 的建议修复。

【讨论】:

应该是JSON.stringify(eval('('+str+')'));,不是我宽恕eval,而是他的字符串不是有效的JSON,所以JSON.parse不起作用。【参考方案20】:

jQuery.parseJSON

str = jQuery.parseJSON(str)

编辑。前提是您有一个有效的 JSON 字符串

【讨论】:

true 我看到的问题是如何将 JSON 字符串转换为对象【参考方案21】:

Douglas Crockford 有一个转换器,但我不确定它是否有助于将坏 JSON 转换为好 JSON。

https://github.com/douglascrockford/JSON-js

【讨论】:

这并没有真正的帮助,因为字符串不是有效的 JSON。

以上是关于将对象字符串转换为 JSON的主要内容,如果未能解决你的问题,请参考以下文章

java将json字符串转换成对象批量存储数据

js 将json字符串转换为json对象或json对象转换成json字符串

Jackson 对象和JSON的相互转换

json字符串转换成对象,对象为空,如何解决

jQuery怎么把JSON格式的字符串转换为JSON对象

JavaScript:如何将JSON对象转换成JSON字符串呢