2012年5月29日火曜日

javascriptでJSONをPOSTしてみてPHPで受け取る。

前回のつづきで、javascriptでObjectを生成し、
それをJSON化し、それをPHPでPOSTで受け取るテストをしてみます。
テストとしては、どうやって文字列処理をすればいいのかってことですね。
また、javascriptからPOSTする方法も含めてテストしてみます。

ってことで、こんなコードでテスト

  1. <script type="text/javascript">  
  2.  var s = "【\u0027】"// '  
  3.  s += "【\u0022】";  // "  
  4.  s += "【\u005c】";  // \  
  5.  s += "【\u002f】";  // /  
  6.  s += "【\u000d】";  // 0d \r  
  7.  s += "【\u000a】";  // 0a \n  
  8.  s += "【\u0009】";  // tab  
  9.  var OJ = function() {};  
  10.  var o = new OJ();  
  11.  o.dat1 = s;  
  12.  var ss = JSON.stringify(o);  
  13. // alert(ss + " / " + ss.length);  
  14.  jspost("01.php","param",ss);  
  15. </script>  
  16. php  
  1. $a = Var_Dump::display($_POST,true);  
  2. echo $a;  
で、結果は、、
  1. ------------------POST------------------  
  2. array(1) {  
  3.   param => string(77) {\"dat1\":\"【\'】【\\\"】【\\\\】【/】【\\r】【\\n】【\\t】\"}  
  4. }  
  5.   
  6. ってことは、、、  
  7. {"dat1":【'】【\"】【\\】【/】【\r】【\n】【\t】}  
  8. が  
  9. {\"dat1\":\"【\'】【\\\"】【\\\\】【/】【\\r】【\\n】【\\t】\"}  
  10. になってるってことです。  
じゃぁこれをどうやって取り込むかってことですね。
まぁJSONできてるから、JSONをdecodeできる文字列に変更する必要があるわけです。
まず、これはPHPの設定になるわけですが、文字のエンコードを調べます。
echo mb_detect_encoding($param);
ってやってみると、、
UTF-8
となりました。これが「UTF-8以外でいいことなんて、とりあえず何もありませんから、PHPは全てUTF-8前提で考えます。
ってことで、var_dumpでこういう結果↓をえるためには、
  1. array(1) {  
  2.   dat1 => string(52) ◆【'】【"】【\】【/】【  
  3. 】【  
  4.                      】【 】  
  5. }  
PHP側で、こういう↓文字列処理をすればいいことになります。
  1. $param = $_POST['param'];  
  2. $param = preg_replace("/\x5c\x5c\x22/",  "\x22",$param);  //【\"】 を 【"】 にする  
  3. $param = preg_replace("/\x5c\x5c\x27/",  "\x27",$param);  //【\'】 を 【'】 にする  
  4. $param = preg_replace("/\x5c\x5c\x5c\x5c/""\x5c\x5c",$param); //【\\】 を 【\】 にする  
もちろん、preg_replaceなので配列にして渡してもいいんですが、、、
そうやったからって言って、速度が速くなるわけでもないので(実験しました)、見やすいように3行にしました。

関数としてはたいしたことない関数。
  1. function objectFromJsJson($v){  
  2.  $vv = preg_replace("/\x5c\x5c\x22/",  "\x22",$v);  // 【\"】 を 【"】 にする  
  3.  $vv = preg_replace("/\x5c\x5c\x27/",  "\x27",$vv);  // 【\'】 を 【'】 にする  
  4.  $vv = preg_replace("/\x5c\x5c\x5c\x5c/""\x5c\x5c",$vv); // 【\\】 を 【\】 にする  
  5.  $json = json_decode($vv,true);  
  6.  return $json;  
  7. }  

しかしここで、PHPでencodeすると、こんな文字列になります。
  1. //【コード】  
  2.  $str = json_encode($json);  
  3.  echo $str;  
  4. //【結果】  
  5. {"dat1":"\u25c6\u3042\u3010'\u3011\u3010\"\u3011\u3010\\\u3011\u3010\/\u3011\u3010\r\u3011\u3010\n\u3011\u3010\t\u3011"}  
日本語が\u表記になります。まぁ、文字のエンコードの問題があるので、この方が扱いやすいといわれればその通りかもしれません。

2012年5月25日金曜日

JSONのencode/decodeの注意な件。

現在、JSONを、以下の4言語で使用中なのですが、
エンコード関係のまとめを一度しなきゃいけないと思ってたので、
ちょっとまとめます。
もちろん、ASとJSは、基本的にはECMAスクリプトですが、
使うライブラリの問題もしれないので、分けます。

(1)C++ → 自前処理
(2)php → json_decode/json_encode関数
(3)ActionScript → com.adobe.serialization.json.JSONにおける、encode,decode
(4)javascript → JSON.stringify/JSON.parse関数(evalは使わない)

ということで、C++の場合は、自分でやってるので、特に言及しません。

問題になりそうなのは、主に、記号類。
その中でも、
【/】【\】【'】【"】【改行】
が重要だと思うので、これらをそれぞれで入力したとき、JSONに変換したとき、POSTで受け取るときなどをまとめてみます。

●テスト1
javascriptでオブジェクトを生成して、それをJSON文字列化。


  1. <h1>01.html</h1>  
  2. <script type="text/java script">  
  3.  var s = "【\u0027】"// '  
  4.  s += "【\u0022】";  // "  
  5.  s += "【\u005c】";  // \  
  6.  s += "【\u002f】";  // /  
  7.  s += "【\u000d】";  // 0d \r  
  8.  s += "【\u000a】";  // 0a \n  
  9.  s += "【\u0009】";  // tab  
  10.   
  11.  alert(s);  
  12.  var OJ = function() {};  
  13.  var o = new OJ();  
  14.  o.dat1 = s;  
  15.  var ss = JSON.stringify(o);  
  16.  alert(ss);  
  17.   
  18.  var sss = "";  
  19.  for(var w=0;w<ss.length;w++){  
  20.   var v = ss.charCodeAt(w);  
  21.   if(v != 12304 && v != 12305) sss += "-" + v.toString(16);  
  22.  }  
  23.  alert(sss);  
  24. </script>  
結果
で、最後の16進コードをもとに見てみると、
【’】【¥”】【¥¥】【/】【¥r】【¥n】【¥t】
である。(全角表示)
ようするに、【’】と【/】は、escapeされない。まぁそういぅ仕様だわね。。
まぁ、あたりまえの事を、一応やってみて確認することが重要なのです。
なんで、16進コードなんかで見るかっていうと、
こんな簡単なコードでも、ブラウザによってalertの表示が違うんですよね。TABとか¥rとかね。 こんな簡単な例だと間違えないけど、javascriptを動的に文字列で作り出したりしてるときに気を抜いていると、思わぬことになるのです。