[PHP] $.ajaxで送信したデータのjson_encodeに失敗する


原因:エスケープされていなかったから

『"(ダブルコーテーション)』
『\(バックスラッシュ)』
『/(スラッシュ)』
『\b(バックスペース)』
『\f(改ページ)』
『\n(改行)』
『\r(キャリッジリターン)』
『\t(バックスペース)』

JSONでは上記の文字を含めるときにエスケープしなければいけません。プログラムのソースコードとかを記事に書くと""や/などはよく使うので引っかかり安いです。

そこまではまあ当たり前なのですが、今回引っかかったのはUrlエンコードとの兼ね合いでした。

"あ"

という文字列を$.ajaxで送信する時に、先にencodeURIComponent()でUrlエンコードし、その後JSON.stringify()でStringにしたものをPHP側に渡し、urldecode()しjson_decode()すると失敗します。

これはurldecodeした時のJSONが{"data":""あ""}みたいになってしまうからです。

$.serialiseでフォームのデータを取得し、それを加工したものをJSON.stringify()して送信したらこうなりました。

通常はJSON.stringify()がエスケープ文字を追加してくれますが、Urlエンコードされた文字は%22みたいになっておりエスケープ文字ではないのでエスケープされずにPHP側に渡ってしまうわけです。

なので私は$.serialise($.serializeArray)で取得したデータをdecodeURIComponent()してからJSON.stringify()でエスケープ&JSON化してencodeURIComponent()でUrlエンコードし直してPHPに渡しました。

そこでふと疑問に思ったのはajax通信でもUrlエンコードって必要なのだろうか?ってことですが、やっておいて損はなさそうなのでやっておきました。

 

$.ajaxでオブジェクトを送信した時のエラー


$.ajax()でJavaScriptのオブジェクトをPHP側に渡そうとしたら以下のエラーが発生しました。

too much recursion

オブジェクト型ではなくstring型ならいけるかと思いJSON.stringify()して送信してみましたが今度は

TypeError: cyclic object value

というエラーが発生。

エラーについて調べて見たところ、無限ループしてしまっていたようです。

その原因は循環オブジェクト参照構造体をそのまま処理していたからでした。

参考リンク

JSON.stringify()の第2引数には関数または配列を渡すことができ、これにより挙動をコントロールできるので変換するといいようです。

■関数を渡す

const obj = { id: 1, name: "js-primer", bio: null };
const replacer = (key, value) => {
    if (value === null) {
        return undefined;
    }
    return value;
};
console.log(JSON.stringify(obj, replacer)); // => '{"id":1,"name":"js-primer"}'

■配列を渡す

const obj = { id: 1, name: "js-primer", bio: null };
const replacer = ["id", "name"];
console.log(JSON.stringify(obj, replacer)); // => '{"id":1,"name":"js-primer"}'

id,nameプロパティだけがホワイトリストとして使われ、 その配列に含まれる名前のプロパティだけが変換されます。

参考リンク

新しくオブジェクトを作って元のオブジェクトをループで回してコピーし直してもいけるかもしれません。また参照構造体にならないように一旦配列とかにデータを入れ直して。試してないのでわかりませんが。

 

 

ブラウザのキャッシュを強制クリアする


CSSやJavaScript、.htaccessファイルを更新した時、ブラウザがキャッシュを読み込んでしまって反映されないことがよくあります。

そのような場合まず試すといいのは「ハード再読み込み」。Windowsの場合Ctrl+F5キー。

対象のWebページの画像や各種ファイル(CSSやJavaScriptなど)を、キャッシュを使わずにリロードします。

しかし、この機能は対象ページに直接由来していない(間接的に読み込まれる)ファイル・データについてはキャッシュが利用されてしまうので、確実に強制的にキャッシュを削除するにはブラウザの設定からキャッシュを削除します。やり方は以下のページに詳しく書いてあります。

なお、デベロッパーツールを使うと「キャッシュの利用を禁止」しF5キーの更新だけでキャッシュを使わない開発ができるようになるようです(上のUrlを参照)。

[WordPress] 5.0以降でTinyMCEを使えるようにする


WordPress5.0のメジャーバージョンアップしてからエディタがブロックエディターなるものに変わってしまい使いづらくて仕方ありませんでした。従来のTinyMCE Advancedに戻したいなぁと調べてみたらあっさり。

「Classic Editor」というプラグインをインストールすればいいだけでした。

ブロック型にも長所があるんですが使い慣れているものの方がやはりいいですね。

Copyright© カキノタ:IT-Life