JSON ( JavaScript Object Notation )
JSON/PHPでGET,POST(by my encode)
 単純にencodeURIで送受信しただけの PHPでGET,POST がSafariで文字化けしたので、【Ajax】日本語文字列防忘メモ の「2:単体のPCとサーバーで送受信する場合 」に書いた自家製エンコード方法を試してみます。  一応、今のところ、サーバー側の文字コード設定には依存しない感じがします。Mac Safari1.25もOKです。

 ここで、手製エンコード処理のベースのエンコーダー/デコーダーとして利用しているencodeURIComponent/decodeURIComponentは、ブラウザにかかわらずutf-8として処理してくれるので、どんな文字コード下にあっても安心です。

 この2つのメソッドがエスケープする文字列は下記の通りです。手製でエンコードをカスタマイズする際には、置き換え文字に「エスケープされない文字列」を使うと、実際の文字列なのか置き換えなのかわからなくなりますから、置き換え文字には「# ; / ? : @ & = + $ ,」などの「エスケープされる文字列」を使うべきです。( ちなみに、encodeURI/decodeURI は、下記の予約語「; / ? : @ & = + $ , 」をエスケープしません。)

encodeURIComponent/decodeURIComponentがエンコード/デコードする文字列 ( ECMA-262 3rd Edition 和訳 : 15.1.3 URI 処理関数のプロパティ )
エスケープされない文字列 0 1 2 3 4 5 6 7 8 9 a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z - _ . ! ~ * ' ( ) "%xx形式(xは16進数)"
エスケープされる文字列 # ; / ? : @ & = + $ , 半角空白 その他すべて


 * この件についての考察(<ってほどではないですが)は、【Ajax】日本語文字列防忘メモ の「2:単体のPCとサーバーで送受信する場合 」をご参照ください。つっこみ歓迎です。

 あとの課題としては、たとえば、変換の塩加減をランダムに生成して、セッション毎に同一のenc/decするようにできれば、JavaScript内にも証拠が残りませんし、ましてTCPをモニタするだけでは、そう簡単には解読できなくなくなると思います。多少はデータも小さくできますしね。

  • GETで送/受信
  • POSTで送/受信
  • 関数化してGETで送/受信
  • 関数化してGETで送/受信 2
  • 暫定ライブラリ jslb_ajax02.js


    GETで送/受信

    GETで送信したデータを、受け取ります。



    [ ./test2_myenc.php ]
    <?php
    
    	//POSTとGETを取得
    	$pos = $_POST['test'] ;
    	$get = $_GET['test'] ;
    
    	//出力
    	echo "{ 'POST' : '$pos' , 'GET' : '$get' }";
    	
    ?> 
    
    このtest2_myenc.phpとの間で、送受信を行います。
    使用可能なブラウザ  
     Win   n7 f1 m1 e5 e6 o8,
     Mac   n7 f1 m1 s1 ,
     Linux n7 f1 m1 k3  
    使えないブラウザ 
     Win   n4 e4 o7,
     Mac   n4 e4.5 e5,
     Linux n4 
    <!-- 暫定ライブラリ jslb_ajax02.js --> <script language = "JavaScript" charset = "utf-8" src = "../../../lib/jslb_ajax02.js"></script> <script language = "JavaScript"> <!-- //起動 function sendData1( callback , data , method , fileURL , async ) { //このデータを送ります var senddata = '高橋としろ' //送信データをエンコード var s = encodeURIComponent( senddata ) s = s.split('%').join('/') s = s.split('/E3').join(':') s = s.split('/A').join(';') s = s.split('/8').join(',') s = s.split('/E').join('?') s = s.split(':,1').join('@') //URL生成 encfileURL = fileURL+'?test='+ s //メッセージダイアログ alert("* こんな自家製エンコードで送出します: \n"+encfileURL ) //送信 requestFile( callback , data , method , encfileURL , async ) //メッセージ出力 outputMsg1( "* こんな自家製エンコードで送出しました: <br>"+encfileURL + "<br><br>" ) } //コールバック関数 // 受信時に起動するスクリプト function onloaded1(oj) { //メッセージダイアログ alert("* データを今、受信しました: \n"+oj.responseText +"\nこれからデコードします") outputMsg1( "* データを今、受信しました: <br>"+oj.responseText + " を受信しました。<br><br>") //受信データをJavaScriptとして実行(JSON化) eval("var res =" + oj.responseText ) //受信データをデコード var r = res.GET r = r.split('@').join(':,1') r = r.split('?').join('/E') r = r.split(',').join('/8') r = r.split(';').join('/A') r = r.split(':').join('/E3') r = r.split('/').join('%') var resdata = decodeURIComponent( r ) //メッセージ出力 outputMsg1( "デコードしたら <b>" + resdata + "</b> になりました。<br><br>") alert( "デコードしたら " + resdata + " になりました。") } //メッセージ出力 function outputMsg1(msg) { //出力 document.getElementById('out1').innerHTML += msg } //--> </script> <br> <input type = "button" onclick = "sendData1( onloaded1 , '' , 'GET' , 'test2_myenc.php' ,true)" value = "sendData1( onloaded1 , '' , 'GET' , 'test2_myenc.php' ,true)"> <br> <br> <!-- 出力用DIV --> <div id="out1"></div>


    POSTで送/受信

    POSTで送信したデータを、受け取ります。



    [ ./test2_myenc.php ]
    <?php
    
    	//POSTとGETを取得
    	$pos = $_POST['test'] ;
    	$get = $_GET['test'] ;
    
    	//出力
    	echo "{ 'POST' : '$pos' , 'GET' : '$get' }";
    
    ?> 
    
    このtest2_myenc.phpとの間で、送受信を行います。
    使用可能なブラウザ  
     Win   n7 f1 m1 e5 e6 o8,
     Mac   n7 f1 m1 s1 ,
     Linux n7 f1 m1 k3  
    使えないブラウザ 
     Win   n4 e4 o7,
     Mac   n4 e4.5 e5,
     Linux n4 
    <!-- 暫定ライブラリ jslb_ajax02.js --> <script language = "JavaScript" charset = "utf-8" src = "../../../lib/jslb_ajax02.js"></script> <script language = "JavaScript"> <!-- //起動 function sendData2( callback , data , method , fileURL , async ) { //このデータを送ります var senddata = data //送信データをエンコード var s = encodeURIComponent( senddata ) s = s.split('%').join('/') s = s.split('/E3').join(':') s = s.split('/A').join(';') s = s.split('/8').join(',') s = s.split('/E').join('?') s = s.split(':,1').join('@') //メッセージダイアログ alert("* こんな自家製エンコードで送出します: \n" + s ) //送信 requestFile( callback , "&test="+s , method , fileURL , async ) //メッセージ出力 outputMsg2( "* こんな自家製エンコードで送出しました: <br>"+s + "<br><br>" ) } //コールバック関数 // 受信時に起動するスクリプト function onloaded2(oj) { //メッセージダイアログ alert("* データを今、受信しました: \n"+oj.responseText +"\nこれからデコードします") outputMsg2( "* データを今、受信しました: <br>"+oj.responseText + " を受信しました。<br><br>") //受信データをJavaScriptとして実行(JSON化) eval("var res =" + oj.responseText ) //受信データをデコード var r = res.POST r = r.split('@').join(':,1') r = r.split('?').join('/E') r = r.split(',').join('/8') r = r.split(';').join('/A') r = r.split(':').join('/E3') r = r.split('/').join('%') var resdata = decodeURIComponent( r ) //メッセージ出力 outputMsg2( "デコードしたら <b>" + resdata + "</b> になりました。<br><br>") alert( "デコードしたら " + resdata + " になりました。") } function outputMsg2(msg) { //出力 document.getElementById('out2').innerHTML += msg } //--> </script> <br> <input type = "button" onclick = "sendData2( onloaded2 , '高橋としろ' , 'POST' , 'test2_myenc.php' ,true)" value = "sendData2( onloaded2 , '高橋としろ' , 'POST' , 'test2_myenc.php' ,true)"> <br> <br> <!-- 出力用DIV --> <div id="out2"></div>


    関数化してGETで送/受信

    エンコード部分を関数化し、GETで送信したデータを、受け取ります。 サーバー側は、上記のtest2_myenc.phpとの間で、送受信を行います。


    <!-- 暫定ライブラリ jslb_ajax02.js -->
    <script language = "JavaScript" 
            charset = "utf-8"
            src     = "../../../lib/jslb_ajax02.js"></script>
    
    <script language = "JavaScript">
    <!--
    
    	//起動
    
    	function sendData3( callback , data , method , fileURL , async )
    	{
    
    		//このデータを送ります
    		var senddata = '高橋としろ'	
    		
    		//送信データをエンコード		
    		var s = myenc(senddata)
    
    		//URL生成
    		encfileURL = fileURL+'?test='+ s
    		
    		//メッセージダイアログ
    		alert("* こんな自家製エンコードで送出します: \n"+encfileURL )
    		
    		//送信
    		requestFile( callback , data , method , encfileURL , async )
    
    		//メッセージ出力
    		outputMsg3( "* こんな自家製エンコードで送出しました: <br>"+encfileURL + "<br><br>" )
    	}
    	
    	
    	//コールバック関数
    	//	受信時に起動するスクリプト
    	function onloaded3(oj)
    	{
    	
    		//メッセージダイアログ
    		alert("* データを今、受信しました: \n"+oj.responseText +"\nこれからデコードします")
    		outputMsg3( "* データを今、受信しました: <br>"+oj.responseText 
    			+ " を受信しました。<br><br>")
    
    		//受信データをJavaScriptとして実行(JSON化)
    		eval("var res =" + oj.responseText )
    
    		//受信データをデコード
    		var r = mydec( res.GET )
    		
    		//メッセージ出力
    		outputMsg3( "デコードしたら <b>" + r + "</b> になりました。<br><br>")
    		alert( "デコードしたら " + r + " になりました。")
    
    	}
    	
    	//自家製エンコード
    	function myenc(str)
    	{
    		var s = encodeURIComponent( str )
    		    s = s.split('%').join('/')
    		    s = s.split('/E3').join(':')
    		    s = s.split('/A').join(';')
    		    s = s.split('/8').join(',')
    		    s = s.split('/E').join('?')
    		    s = s.split(':,1').join('@')
    		    return s 
    	}
    
    	//自家製デコード
    	function mydec(str)
    	{
    		var r = str.split('@').join(':,1')
    		    r = r.split('?').join('/E')
    		    r = r.split(',').join('/8')
    		    r = r.split(';').join('/A')
    		    r = r.split(':').join('/E3')
    		    r = r.split('/').join('%')
    		    r = decodeURIComponent( r )
    		    return r 
    	}
    
    	//メッセージ出力
    	function outputMsg3(msg)
    	{
    		//出力
    		document.getElementById('outfunc1').innerHTML += msg
    	}
    
    //-->
    </script>
    <br>
    	<input type    = "button"
    	       onclick = "sendData3( onloaded3 , '' , 'GET' , 'test2_myenc.php' ,true)"
    	       value   = "sendData3( onloaded3 , '' , 'GET' , 'test2_myenc.php' ,true)">
    <br>
    <br>
    	<!-- 出力用DIV -->
    	<div id="outfunc1"></div>
    


    関数化してGETで送/受信 2

    置き換え文字列と工程数を自由に決めて引数で渡せる関数を作り、GETで送信したデータを、受け取ります。 サーバー側は、上記のtest2_myenc.phpとの間で、送受信を行います。


    <!-- 暫定ライブラリ jslb_ajax02.js -->
    <script language = "JavaScript" 
            charset = "utf-8"
            src     = "../../../lib/jslb_ajax02.js"></script>
    
    <script language = "JavaScript">
    <!--
    
    	function sendData4( callback , data , method , fileURL , async )
    	{
    
    		//このデータを送ります
    		var senddata = '高橋としろ'	
    				
    		//送信データをエンコード		
    		var a = myenc2(senddata ,'%--/' ,'/E3--:' ,'/A--;' ,'/8--,' ,'/E--?' ,':,1--@' )
    
    		//URL生成
    		encfileURL = fileURL+'?test='+ a
    		
    		//メッセージダイアログ
    		alert("* こんな自家製エンコードで送出します--: \n"+encfileURL )
    		
    		//送信
    		requestFile( callback , data , method , encfileURL , async )
    
    		//メッセージ出力
    		outputMsg4( "* こんな自家製エンコードで送出しました: <br>"+encfileURL + "<br><br>" )
    	}
    	
    	
    	//コールバック関数
    	//	受信時に起動するスクリプト
    	function onloaded4(oj)
    	{
    	
    		//メッセージダイアログ
    		alert("* データを今、受信しました: \n"+oj.responseText +"\nこれからデコードします")
    		outputMsg4( "* データを今、受信しました: <br>"+oj.responseText 
    			+ " を受信しました。<br><br>")
    
    		//受信データをJavaScriptとして実行(JSON化)
    		eval("var res =" + oj.responseText )
    
    		//受信データをデコード
    		var r = mydec2( res.GET ,'%--/' ,'/E3--:' ,'/A--;' ,'/8--,' ,'/E--?' ,':,1--@' )
    
    		
    		//メッセージ出力
    		outputMsg4( "デコードしたら <b>" + r + "</b> になりました。<br><br>")
    		alert( "デコードしたら " + r + " になりました。")
    
    	}
    	
    	
    	//自家製エンコード
    	//
    	// @param str  第一引数     対象文字列
    	// @param str  第二引数以降 置き換え文字のペアを"--"で結ぶ文字列
    	//             もし、'%--/'なら%を/に置き換える。置き換え処理の順序は
    	//             第二引数から順番に右へ処理していく。
    	//             並び順はmydec2(str)と同じだが、処理の順序が逆。
    	//             これは、myenc2で書いた引数をmydec2へコピーして使える
    	//             便宜を図るための仕様。
    	// @return     エンコード後の文字列
    	// @sample     myenc2(senddata ,'%--/' ,'/E3--:' ,'/A--;' )
    	//
    	//
    	function myenc2(str)
    	{
    		var s = encodeURIComponent( myenc2.arguments[0] )
    		for (var i = 1 ; i < myenc2.arguments.length ; i++ )
    		{	
    			var arg  = myenc2.arguments[i].split('--')
    			s = s.split(arg[0]).join(arg[1])
    		} 
    		return s 
    	}
    
    	//自家製デコード
    	//
    	// @param str  第一引数     対象文字列
    	// @param str  第二引数以降 置き換え文字のペアを"--"で結ぶ文字列
    	//             もし、'%--/'なら/を%に置き換える。置き換え処理の順序は
    	//             最後の引数から順番に左へ処理し、第二引数で終わる。
    	//             並び順はmyenc2(str)と同じだが、処理の順序が逆。
    	// @return     デコード後の文字列
    	// @sample     mydec2(receiveddata ,'%--/' ,'/E3--:' ,'/A--;' )
    	//
    	function mydec2(str)
    	{
    		var r = str
    		for (var j = mydec2.arguments.length-1 ; j >= 1 ; j-- )
    		{
    			var arg  = mydec2.arguments[j].split('--')
    			r = r.split(arg[1]).join(arg[0])
    		}
    		return decodeURIComponent( r )
    	}
    
    
    	//メッセージ出力
    	function outputMsg4(msg)
    	{
    		//出力
    		document.getElementById('outfunc2').innerHTML += msg
    	}
    
    //-->
    </script>
    <br>
    	<input type    = "button"
    	       onclick = "sendData4( onloaded4 , '' , 'GET' , 'test2_myenc_func2.php' ,true)"
    	       value   = "sendData4( onloaded4 , '' , 'GET' , 'test2_myenc_func2.php' ,true)">
    <br>
    <br>
    	<!-- 出力用DIV -->
    	<div id="outfunc2"></div>
    
    

    【 暫定ライブラリ jslb_ajax02.js 】
    //XMLHttpRequestオブジェクト生成
    //createHttpRequest()
    //
    // @returns XMLHttpRequestオブジェクト またはnull
    //
    function createHttpRequest()
    {
    	if(window.ActiveXObject)
    	{
    		try 
    		{
    			return new ActiveXObject("Msxml2.XMLHTTP");
    		} 
    		catch (e) 
    		{
    			try 
    			{
    				return new ActiveXObject("Microsoft.XMLHTTP");
    			} 
    			catch (e2) 
    			{
    				return null;
    			}
    		 }
    	} 
    	else if(window.XMLHttpRequest)
    	{
    		return new XMLHttpRequest();
    	} 
    	else 
    	{
    		return null;
    	}
    }
    
    // requestFile( callback , data , method , fileURL , async )
    //
    // @param callback 受信時に起動する関数名
    // @param data	 送信するデータ
    // @param method "POST" or "GET"
    // @param fileURLリクエストするファイルのURL
    // @param async	Asyncならtrue Syncならfalse
    // --@param user A username for authentication if necessary.
    // --@param password A password for authentication if necessary.
    // パスワード等はとりあえず省略
    //
    function requestFile( callback , data , method , fileURL , async )
    {
    	//XMLHttpRequestオブジェクト生成
    	var oj = createHttpRequest()
    	if( oj == null ) return null
    
    	//ブラウザ判定-->別関数にした方がすっきりする?
    	var ua = navigator.userAgent
    	var safari	= ua.indexOf("Safari")!=-1
    	var konqueror = ua.indexOf("Konqueror")!=-1
    	var mozes	 = ((a=navigator.userAgent.split("Gecko/")[1] )?a.split(" ")[0]:0) >= 20011128 
    	
    	//Konquerorはonloadが不安定http://jsgt.org/ajax/ref/test/response/responsetext/try1.php
    	if(window.opera || safari || mozes)
    	{
    	oj.onload = function () { callback(oj) }
    	}
    	else
    	{
    		oj.onreadystatechange =function () 
    		{
    			if ( oj.readyState == 4 )
    			{
    				callback(oj)
    			}
    		}
    	}
    
    	//open メソッド
    	oj.open( method , fileURL , async )
    
    	
    	if(method == 'POST')
    	{
    		//このメソッドがWin Opera8でエラーになったので、とりあえず分岐2005.5.20
    		if(!window.opera)
    			oj.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
    	}
    
    	//send メソッド
    	oj.send(data)
    
    }
    
    

  • 【作業用掲示板】