質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

正規表現

正規表現とは特定の文字列によるパターンマッチングを行う際に用いられる宣言型プログラミングです。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Q&A

解決済

1回答

4122閲覧

headに呼び出したJSONが空であった時のエスケープ

hibikikudo

総合スコア238

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

正規表現

正規表現とは特定の文字列によるパターンマッチングを行う際に用いられる宣言型プログラミングです。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

1グッド

1クリップ

投稿2016/10/31 11:07

編集2016/11/01 07:51

###前提・実現したいこと
HTMLのheadに呼び出したJSONが空であった時にエラーを出さないよう、エスケープ処理をしたい。

###発生している問題
HTMLのhead内のコードが
<script id="ID" type="application/json"></script>
という形になるので、js側に
if ($('#ID').length) {}
と書く方法が使えず、困っています。

エラーメッセージ

Uncaught SyntaxError: Unexpected end of JSON input

###該当のソースコード

javascript

1if ($('#tagJson').length) { 2... 3}

html

1<script id="tagJson" type="application/json"> 2<!--ここが空--> 3</script>

何卒よろしくお願いいたします。

kei344👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kei344

2016/10/31 13:12

書かれているコードだけではエラーが再現されません。もう少し具体的にお書きください。
guest

回答1

0

ベストアンサー

とりあえずエラーを再現することが出来ました。

HTML

1<script id="tagJson" type="application/json"> 2 3 4 5</script> 6<!-- {}以外のHTMLコメントもJavaScriptコメントもJSONの仕様的にだめなのでエラーが出る -->

JavaScript

1if ($('#tagJson').length) { 2 console.log( $('#tagJson').text() ); // (空文字列) 3 var x = JSON.parse( $('#tagJson').text() ); // Uncaught SyntaxError: Unexpected end of JSON input 4 console.log( x ); 5} // エラーが出る

正規表現で {} にマッチさせれば良いだけなきもします。どちらにせよパースに失敗する可能性があるのであれば、try...catch 文を使うのが良いと思います。

JavaScript

1if ( $('#tagJson').text().match( /[\s\S]*{[\s\S]*}[\s\S]*/g ) ) { 2 var x = JSON.parse( $('#tagJson').text() ); 3 console.log( x ); 4} // エラーが出ない

投稿2016/10/31 18:25

kei344

総合スコア69407

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hibikikudo

2016/11/01 01:49

改行文字を含めてあらゆる文字にマッチさせる(空でない時)という正規表現を使用する方法が、非常に参考になりました。どうもありがとうございました。
think49

2016/11/01 05:29 編集

解決後に指摘するのは気が引けますが、正規表現によるコードは解決になっていないと思います。 <script id="tagJson" type="application/json">[]</script> が null と評価されます。 また、String#matchがうまく機能するのはマッチしてない時に null と評価する為ですが、マッチした時に意図しない動作になる可能性があります。JSON.parse に配列を渡してString型に変換させる事になりますので、['A', 'B'] が "A,B" に変換されてしまいますよね…。 JSON.parse の SyntaxError はエラーに気が付くための機構なので底を回避する必要はないと考えます。 重要なのは JSON 文字列でない場合にどんな文字列が入っているのか、という条件付けです。 この場合は <script id="tagJson" type="application/json"></script> ですから空文字である事が明白ですね。 ならば、空文字だけ例外処理すればいいのではないでしょうか(空白文字が入る可能性があるなら trim() すればいいでしょう)。 https://jsfiddle.net/exwvfwvb/
hibikikudo

2016/11/01 05:39

丁寧にご説明いただきありがとうございます。Undefined, Null, NaNあたりを混同してしまうことがあるので、気をつけていきたいと思います。
kei344

2016/11/01 06:11 編集

To: think49さん > <script id="tagJson" type="application/json">[]</script> が null と評価されます。 空文字以外の状況がどのようになるのかが読めなかったため、入るのはオブジェクトと決め打ちして回答しました。雑な回答ですね・・・。 > マッチした時に意図しない動作になる可能性があります。JSON.parse に配列を渡してString型に変換させる事になりますので、['A', 'B'] が "A,B" に変換されてしまいますよね…。 マッチした結果を変数に代入して利用しているわけではないので、その挙動になるでしょうか。 > SyntaxError はエラーに気が付くための機構なので底を回避する必要はないと考えます。 エラーについては、空文字列が入る可能性が有るという状況から、「何が入るかそこまで制御できない」状況かと思い、書いています。JSON部分が問題なくパースできるも(はず)のなのであればエラーは隠すべきではないということは私もそう思います。 > https://jsfiddle.net/exwvfwvb/ script.length は少なくともFirefoxにおいて、改行を1文字と捉えます。 最初それがあったので、下記のように提示するつもりだったのですが、「どうせオブジェクトが入るだろう」と今の回答になっています。 if ( $('#tagJson').text().replace( /[\r\n\s]/g ).length > 1 ) {}
think49

2016/11/01 06:34

To: kei344 さん > マッチした結果を変数に代入して利用しているわけではないので、その挙動になるでしょうか。 申し訳ありません。私が読み違えておりました。(なぜこんな勘違いをしたのやら…) 改めて読み直しましたが、この正規表現は部分一致なので /{[^}]*}/.test($('#tagJson').text()) と同じなんですね(最も、完全一致でも /{[^}]*}/ と等価ですが)。 "hoge {} foo", "{}}" を SyntaxError とし、"hoge foo" は SyntaxError とせず、"[]", "null" をパースしない設計と読みました。 ブラックリスト方式(空文字を排除)とホワイトリスト方式({} のみ許可)の違いがあるようです。 そういえば、JSON.parse("null") でパースされる挙動が正しいのか気になっていたのを思い出しました。
kei344

2016/11/01 07:47

To: think49さん > /{[^}]*}/ あ、そんな簡単に・・・。改行にマッチしない気がして冗長に書いていました。 > "hoge {} foo", "{}}" を SyntaxError とし、"hoge foo" は SyntaxError とせず、"[]", "null" をパースしない設計と読みました。 そうですね。くずれたJSONを受け取る(自分で配信してしまう)可能性は否定できないのでそういう方針になることが多いです。また、"[]", "null" は「受け取っていないと同じ」と判断することで切り捨てていますね。(空配列やnullが「意味のある」設計の場合は当然違う手段を考えます) > JSON.parse("null") でパースされる挙動が正しいのか 仕様( http://www.json.org/ )にはJSONを構成するものとして、数値やオブジェクトとともにnullも書かれているので、nullを返す(パースする)のは挙動として(とりあえず)おかしくないと思いますよ。 私は、「JSON is built on two structures」として(JavaScriptで言うと)配列とオブジェクトが書かれているので、最小単位はどうしてもその二つな気がします。なのでJSON.parse("true")も変に感じます。(なので避けて使ってしまう)
think49

2016/11/01 08:28 編集

To: kei344 さん > あ、そんな簡単に・・・。改行にマッチしない気がして冗長に書いていました。 改行にマッチしないのは . で [^abc] は改行にマッチしますね。 厳密には両者はマッチする範囲に差がありますが、マッチするか否かの観点ではどちらも変わりません。 /{[\s\S]*}/.exec('{}}'); // ["{}}"] (最長一致なので最後尾の } まで消費する) /{[^}]*}/.exec('{}}'); // ["{}"] > (空配列やnullが「意味のある」設計の場合は当然違う手段を考えます) 空配列を無意味なデータとするのは分かるのですが、"[1, 2, 3]" を切り捨てるのはどうかな、と思っていました。 配列を望まず、{} を決め打ちして new Object を保証しているのでしょうか。 パース前に配列とオブジェクトを区別する設計にした場合、先述の正規表現の方法では {"a":[1,2,3]} と [1,2,3] を区別できない以上、緩い判定になると考えています。 厳密に判定するならどちらにしても、パース後の判定が必要になるかなと。 var object = JSON.parse('{"a":[1,2,3]}'); if (object && Object.getPrototypeOf(object) === Object.prototype) { // object が new Object なら console.log(object); // {a: [1, 2, 3]} } > 仕様( http://www.json.org/ )にはJSONを構成するものとして、数値やオブジェクトとともにnullも書かれているので、nullを返す(パースする)のは挙動として(とりあえず)おかしくないと思いますよ。 なるほど、ありがとうございます。 > 私は、「JSON is built on two structures」として(JavaScriptで言うと)配列とオブジェクトが書かれているので、最小単位はどうしてもその二つな気がします。なのでJSON.parse("true")も変に感じます。(なので避けて使ってしまう) 私は仕様に厳格なコードを好むので、必要であれば JSON.parse した後に判定ロジックを入れてます。
kei344

2016/11/01 08:50

To: think49さん > "[1, 2, 3]" を切り捨てるのはどうかな、と思っていました。 単純に想定から抜け落ちていました。 > 厳密に判定するならどちらにしても、パース後の判定が必要になるかなと。 その通りだと思います。 いつも的確な指摘をありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問