オブジェクト文字列をJSONに変換する


165

JavaScript(またはjQuery)を使用してオブジェクトを説明する文字列をJSON文字列に変換するにはどうすればよいですか?

例:これを変換します(有効なJSON文字列ではありません):

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

これに:

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

eval()できれば使用を避けたいです。


そもそもなぜ文字列が有効なJSONではないのですか?それをどのように生成していますか?
ロケットハズマット

2
文字列は次のdataように-attrubuteに格納されます。HTMLで<div data-object="{hello:'world'}"></div>一重引用符を使用したくないので(おそらく信頼されないでしょう)
snorpey

5
@snorpey:<div data-object='{"hello":"world"}'></div>100%有効なHTMLです(単一引用符はそれを信頼するかどうかに関係していますか?)。このようにするJSON.parseと、それだけで問題なく動作します。 注:キーも引用符で囲む必要があります。
Rocket Hazmat 2012年

@ロケットあなたの努力をありがとう!HTMLで一重引用符(100%有効です)とJSON表記を使用する必要がある方法を見つけたかっただけです。
snorpey 2012年

@snorpey:回避策は、最初にJSONをHTML属性に配置しないことです。二重引用符を使用して、JSONの引用符をエスケープできると思います<div data-object="{\"hello\":\"world\"}"></div>。属性で有効なJSONを使用したくない場合は、独自の形式を作成して自分で解析する必要があります。
Rocket Hazmat 2012年

回答:


181

文字列は、信頼できるソースからのものである場合、あなたは使用することができeval、その後JSON.stringify、結果を。このような:

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

メモときにeval、オブジェクトリテラル、それはそうでない場合は、中括弧ではなく、オブジェクトのブロックとして解析され、括弧内にラップする必要があります。

また、質問の下のコメントにも同意します。有効なJSONでオブジェクトをエンコードしてから始め、解析、エンコード、そしておそらく再度解析する必要がないようにする方がはるかに良いでしょう。HTMLは単一引用符で囲まれた属性をサポートします(文字列内の単一引用符はすべてHTMLエンコードしてください)。


これは意味がありません。文字列が信頼できるソースからのものである場合、代わりに変換する理由は有効なjsonとして作成します。
allenhwkim 2014年

2
@allenhwkimアイデアは、無効なJSONから有効なJSONにeval変換するため、文字列をJavaScriptオブジェクトに変換します(文字列が有効なJavaScriptを表す限り、有効なJSONでなくても機能します)。次にJSON.stringify、オブジェクトから(有効な)JSON文字列に変換します。eval文字列がクロスサイトスクリプティング攻撃の可能性を開くJavaScriptを文字通り実行する可能性があるため、文字列が信頼できるソースからのものでない場合、呼び出しは危険です。
Matthew Crumley、2014年

2
この場合、たとえば次のように文字列が構築されていると、evalは悪いことをします。var str = "(function(){console.log(\" bad \ ")})()";
ロンド

eval()を使用すると、JSコードが実行されます。簡単に悪用される可能性があります。
FisNaN 2018

@allenhwkim:ソースを信頼することはありません。ITへの信頼とは、確認、確認、再確認を意味します。
Laszlo Varga、

110

文字列は有効なJSONではないため、JSON.parse(またはjQueryの$.parseJSON)は機能しません。

1つの方法は、を使用evalして「無効な」JSONを「解析」し、stringifyそれを有効なJSONに「変換」することです。

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

無効なJSONを「修正」する代わりに、最初は有効なJSONから始めることをお勧めします。str生成方法は、生成される前ではなく、生成される前に修正する必要があります。

編集:あなたは言った(コメントで)この文字列はデータ属性に保存されています:

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

ここで修正することをお勧めしますJSON.parse。まず、キーと値の両方を二重引用符で囲む必要があります。これは次のようになります(HTMLで単一引用符で囲まれた属性は有効です)。

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

これで、JSON.parse(またはjQueryの$.parseJSON)を使用できます。

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


43

以下のリンクで簡単なコードを使用してください:

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:いいえ、プリミティブラッパーは使用しないでください。
Ry-

1
JSON.parse()は、@ LouiseMcMahonで述べられているように、ここで受け入れられる答えである必要があります
pixel 67

24

この小さな関数が無効なJSON文字列を有効な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+'"'})         
}

結果

var 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を無効化しようとしていますが、これは良い解決策のようです。一定の置換を手動で処理する必要がありますが、少なくともこれらのケースを含めることができます。
ravemir 2016年

1
それはほぼ完璧です。が: いずれかの値の場合は機能しません。
seler

9

注意して使用してください(の理由eval()):

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

として呼び出す:

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

3
匿名の投票者に。より良いソリューションを提供するようにあなたに挑戦します。それとは別に、反対票の理由はいいでしょう。
Tomalak 2012年

1
@ロケット:あなたは間違っています。a)eval()それを行う唯一の方法です。b)OPに警告しました。c)マシュー・クラムリーの答えを見て、より良い説明を考えてください。(ああ、d)ステートメントeval()が悪いのは、この一般化された形式ではナンセンスです。)
Tomalak 2012年

2
@ロケット:ああ、そこに誤解があります。申し訳ありませんが、反対票はあなたのものだと思いました。:)
Tomalak

1
@kuboslav:正常に動作しますが、テストさえしましたか?彼がやってeval("var x = " + str + ";")いるのは完全に有効なJSです。する必要はありませんvar x = ({a:12})
ロケットハズマット

2
@kuboslav IE7はネイティブJSONをサポートしていないため、IE7では機能しません。を使用するとすぐに機能しますjson2.js。そんなにトリガーハッピーにならないでください。
Tomalak 2012年

4

免責事項:自宅で、または他の開発者があなたを真剣に受け止めることを必要とするものに対してこれを試さないでください:

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

そこで、私はやった。
それをしないようにしてください、evalはあなたにとって悪いです。上記のように、古いブラウザー(IE7以下)にはCrockfordのJSONシムを使用します。

このメソッドでは、文字列が有効なJavaScriptである必要がありますである JSONにシリアル化できるjavascriptオブジェクトに変換されます。

編集: Rocketの提案に従って修正。


それはであるはずですがJSON.stringify(eval('('+str+')'));eval彼の文字列は有効なJSONでJSON.parseはないため、機能しません。
ロケットハズマット

4

私はこの古いスレッドに興味がある人に答えを出しました。

を使用せずに不正なJSON文字列をJavaScriptオブジェクトに変換するjQueryプラグインとデモ用のHTML5 data- *パーサーを作成しました。eval()

以下のHTML5 data- *属性を渡すことができます。

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

オブジェクトに:

{
    hello: "world"
}


2

この偉業を達成するはるかに簡単な方法があります。ダミー要素の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(コンソールを開く)


2

結果に対して「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);

ここに画像の説明を入力してください


1

角括弧がないevalと中括弧内のコードがコマンドのブロックと見なされるため、角括弧を記述する必要があります。

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

1

あなたの最善かつ最も安全な賭けは、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>


1

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 }

出典: MDN2ality


0

上記の簡単な例では、2つの単純な正規表現置換を使用してこれを行うことができます。

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

大きな警告:この素朴なアプローチは、オブジェクトに'または文字を含む文字列がないことを前提としています:。たとえば、次のオブジェクト文字列を使用せずにJSONに変換する良い方法は考えられませんeval

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

0

それの奇妙なことに、あなたはあなたの文字列を経由して変換することができます 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>


0

var str = "{hello: 'world'、Places:['Africa'、 'America'、 'Asia'、 'Australia']}" var fStr = str .replace(/([Az] *)(:)/ g、 '"$ 1":').replace(/ '/ g、 "\" ")

console.log(JSON.parse(fStr))ここに画像の説明を入力してください

申し訳ありません、私は私の電話にいます、これは写真です。


0

正規表現が1つあり、evalを使用しないソリューション:

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

これは、複数の行で機能し、単一引用符「string」が二重引用符「string」に置き換わった場合に発生する可能性のあるすべて(/ gフラグ)で機能するはずです。


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

-1

多分あなたはこれを試さなければなりません:

str = jQuery.parseJSON(str)

質問は「またはjQuery」を指定しました。利用できる場合、これは完璧なソリューションです。
エクロポリス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.