JSONでUncaught SyntaxError: Unexpected end of inputエラーに対処
webの進歩は日進月歩ながら毎日進化してゆくため、気が付いたら大きく変化していることがあります。
その一つが「JSON」です。
webはリンクをクリックして次のページを表示するのが一般的です。
リンクをクリックしたら、新しいページが再表示されます。
例えば改ページリンクであっても同様です。
ところがJSONはwebを再表示せずにPHP等と非同期通信ができます。
便利なのですが、とっつきにくい特徴があります。
今回JSONを組んでいて、よくわからないエラーに振り回されましたので、忘備録として記録いたします。
JSONとはそもそも何?
JSONって知っているようでよくわからないものです。
まずはJSONのサンプルをご覧いただければ幸いです。
サンプルは、ボタンを押すと、PHP側で用意した現在時刻をHTML側へ送り返しています。
JSONのすごいところは、PHPからの値を再表示せずに受け取れる点です。
PHPと通信できるということは、PHPを経由してMYSQLからのデータ取得もできるということです。
ただ欠点は、「とにかくやり方がわかりにくい」という点です。
このわかりにくさから、仕組みを理解しておらず、今回のエラーに難儀しました。
現象はこのような感じです
現象が発生するサンプルをご参照いただければ幸いです。
現象はPHPからの戻りを受け取った後エラーになり動作しません。
SyntaxError が発生し処理が実行されませんでした。
JSONなので、HTML側の問題か、PHP側いずれかの問題だと思われます。
ただ、単純な文法エラーというわけではないため、何がいけないのかさっぱりわかりません。
それでも原因の手掛かりは「記述方法」にあります
SyntaxErrorは、記述に何かしらの問題がある場合に発生します。
そこでまずはソースを確認しました。
HTMLのソース
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
<!doctype html> <html> <head> <meta charset="shift_jis"> <title>JSONテスト</title> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script> <script> $(document).ready(function() { $("#btn button").click(function () { $.ajax({ url: 'adderror.php', type: 'post', dataType: 'json', }) .done(function ($sts) { $("#result").text("JSON 処理成功しました"); $("#add").append($sts["html"]); }) .fail(function () { $('#result').text("JSON 処理失敗しました"); $('#errmsg').html(error(arguments)); console.log(arguments); }); }); function error($args) { var error; if ($args[2]) { try { error = JSON.parse($args[0].responseText).error.toString(); } catch (e) { error = "例外エラー(" + $args[2] + "):" + $args[0].responseText; } } else { error = $args[1] + "(PHPのリクエストに失敗しました)"; } return error; } }); </script> <style type="text/css"> article { width: 800px; margin-right: auto; margin-left: auto; padding-top: 30px; padding-bottom: 30px; text-align: center; } #result { padding: 10px; margin-bottom: 10px; border: 1px solid #CCC; } #errmsg { margin-bottom: 30px; color: #F00; } p { padding-top: 20px; padding-bottom: 20px; border-bottom-width: 1px; border-bottom-style: dashed; border-bottom-color: #CCC; } .green { color: #390; font-weight: bold; } </style> </head> <body> <article> <h1>JSON処理でエラーがでるパターン</h1> <div id="result">下のボタンを押してください</div> <div id="errmsg"></div> <div id="btn"><button>現在時刻を表示します</button></div> <div id="add"></div> </article> </body> </html> |
PHPのソース
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<?php $date = date("Y/m/d H:i:s"); $data = "<p>ただいまの時刻は<br>[ <span class=\"green\">${date}</span> ]</p>"; $sts = array("html"=>$data); /** JSON 出力 */ echo json_encode($sts); exit(); ?> |
ソースに問題があるといわれても、どう見ても問題があるように見えません。
ここで手詰まりになりました…。
さらなる情報がないかググってみたところ、気になる記事を見つけました。
JSONはUTF-8以外はすべてエラーになる
PHPから日本語テキストをJSONで返信する場合、UTF-8以外の文字コードだとすべてエラーになるというものでした。
そういえば、PHPは使っているテキストエディタのデフォルトである「Shift-JIS」で記述していました。
つまり、日本語テキストをShift-JISで記述しています。
原因はこれだと思い修正しました。
PHPの記述を次のように修正
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<?php $date = date("Y/m/d H:i:s"); $data = "<p>" . mb_convert_encoding("ただいまの時刻は", "UTF-8", "SJIS-win") . "<br>[ <span class=\"green\">${date}</span> ]</p>"; $sts = array("html"=>$data); /** JSON 出力 */ echo json_encode($sts); exit(); ?> |
日本語テキストで出力している部分「ただいまの時刻は」の文字を、mb_convert_encoding関数でUTF-8へ変換しました。
テキストエディタの文字コードをUTF-8にする方法もありますが、あとから「原因なんだっけ?」と振り返った時に、ソースにmb_convert_encodingの記述があると思い出しやすいので、あえて文字コード変換を行います。
その結果、エラーが発生しなくなりました。
そのサンプルはこちらです。
今回は、JSONのインターフェース(HTML→PHPへの情報渡し/PHP→HTMLへの情報戻し)がよくわからなかったため四苦八苦しました。
また、まさかの文字コードの影響が原因でした。
さすがに、「JSONはUTF-8以外はエラー」を知っていなけれが解決できない問題でした。
よくよくググることは大事です。
本記事がお役に立てば幸いです。