2015年2月14日土曜日

JSON形式のハンドリング

couchdbとアクセスするためJSONを扱えるよう、JavaScript/jQueryによるJSONの処理方法を調べてます。

$.ajax()でGETすると、JSON形式でcouchdbからの応答をObjectの型式で読み込みます。データにアクセスするのは楽なのですが、デバッグ用に文字列で全体を表示しようと思うとすごいめんどくさい。調べてみると、stringify()という関数がよくでてきます。以下の様なスプクリプトをstringify.jsとか保存しておいてjQueryを拡張して使います。

(function($) {
 $.extend({
  stringify: function stringify(obj) {
   
   var t = typeof (obj);
   if (t != "object" || obj === null) {
    // simple data type
    if (t == "string") {
     obj = '"' + obj + '"';
    }
    return String(obj);
   }
   else {
    var n, v, json = [];
    var arr = (obj && $.isArray(obj));
     
    for (n in obj) {
     v = obj[n];
     t = typeof(v);
     if (obj.hasOwnProperty(n)) {
      if (t == "string") {
       v = '"' + v + '"';
      }
      else if (t == "object" && v !== null) {
       v = jQuery.stringify(v);
      }
      json.push((arr ? "" : '"' + n + '":') + String(v));
     }
    }
    return (arr ? "[" : "{") + String(json) + (arr ? "]" : "}");
   }
  }
 });
})(jQuery);

皆んな困ってるようで、ググってると結構いろんな所ででてきます。今度は、$.ajax()でPUTしようとすると、送信データの形式がObjectではなくJSON形式の文字列で渡さないといけません。 これではjQueryにstringify()がなぜ実装されていないのか訳がわかりません。 さらにググると、JavaScript1.7からJSON.stringify()というのが実装されているのがわかり、納得しました。結局、ライブラリとして作ったファイルは一瞬で必要なくなったかの様に思えたのですが、話はこれで終わりませんでした。

ところがどっこい、IE8だとこのJSONというオブジェクトが実装されてません。ブラウザに実装されているJavaScriptのバージョンをチェックするスクリプトがあったので、調べてみると1.3です!(IEだと正確にはJScriptですが)会社関係だとシステムが対応してるのがまだIE8というところが多いと聞いています。(XPがダメになった時に、IE6からやっとあがったばっかりという所が多いと思います) 結局、当面はstringify.jsを使うようにしたほうがいいようです。
ちなみに以下に、そのスクリプトを示します。


<SCRIPT Language="JavaScript">
// Java Script 1.0以降で動作する関数
function funcGetVer() { return "1.0" ; }
</SCRIPT>

<SCRIPT Language="JavaScript1.1">
// Java Script 1.1以降で動作する関数
function funcGetVer() { return "1.1" ; }
</SCRIPT>

<SCRIPT Language="JavaScript1.2">
// Java Script 1.2以降で動作する関数
function funcGetVer() { return "1.2" ; }
</SCRIPT>

<SCRIPT Language="JavaScript1.3">
// Java Script 1.3以降で動作する関数
function funcGetVer() { return "1.3" ; }
</SCRIPT>

<SCRIPT Language="JavaScript1.4">
// Java Script 1.3以降で動作する関数
function funcGetVer() { return "1.4" ; }
</SCRIPT>

<SCRIPT Language="JavaScript1.5">
// Java Script 1.3以降で動作する関数
function funcGetVer() { return "1.5" ; }
</SCRIPT>

<SCRIPT Language="JavaScript1.6">
// Java Script 1.3以降で動作する関数
function funcGetVer() { return "1.6" ; }
</SCRIPT>

<SCRIPT Language="JavaScript1.7">
// Java Script 1.3以降で動作する関数
function funcGetVer() { return "1.7" ; }
</SCRIPT>

<SCRIPT Language="JavaScript1.8">
// Java Script 1.3以降で動作する関数
function funcGetVer() { return "1.8" ; }
</SCRIPT>

<SCRIPT Language="JavaScript1.9">
// Java Script 1.3以降で動作する関数
function funcGetVer() { return "1.9" ; }
</SCRIPT>

<SCRIPT Language="JavaScript2.0">
// Java Script 1.3以降で動作する関数
function funcGetVer() { return "2.0" ; }
</SCRIPT>

<SCRIPT Language="JavaScript">
// Java Script のバージョンを取得して表示する関数
  function funcVerDisp()
{
var strVersion = funcGetVer() ;
alert( 'このブラウザーの Java Scriptのバージョンは\n\t' + strVersion + ' です。\n' ) ;
}
</SCRIPT>

なんか同じ関数を何度も定義してますが、SCRIPTでのlanguage指定がキモです。ここで対応するバージョンを指定していますが、同じ関数定義をすると最後のものが有効になります。そこでhtml内のbuttonからonclickでfuncVerDisp()をCallしてやるようにすれば、バージョン名をダイアログで表示してくれます。ちなみに私が普段使いしているchromeは1.7でした。(最初にこのテクニックを紹介していたサイトでは、SCRIPTの中で、Type="javascript"というtype属性をつけていましたが、それではうまく動きませんでした。調べてみるとtype属性はスクリプトバージョンには関係しないので、返ってそれ以降の指定が無効になってしまうようです。)

結局、stringify()の使い方ですが、以下のように使います。

var jsonStr = '{"message":"success", "returnCode":0}';
json = $.parseJSON(jsonStr);

var str = $.stringify(json);

最初にJSON形式の文字列をjQueryの関数でObject形式にしていますが、JavaScript1.7だと、JSON.parse()という同様のものがあります。しかしこれもIE8では使えないので、色んな環境で動かしたいならjQueryにまかせた方がいいようです。

0 件のコメント:

コメントを投稿