HTTP通信を使って、サーバー上のデータを取得する

 

HTTP通信とはなにか?

HTTP通信とは何か?と聞かれると答えられませんので、今回使用する予定のXMLHttpRequest についてWikipediaを調べました。

XMLHttpRequest (XHR) は、JavaScriptなどのウェブブラウザ搭載のスクリプト言語でサーバとのHTTP通信を行うための、組み込みオブジェクト(API)である。
すでに読み込んだページからさらにHTTPリクエストを発することができ、ページ遷移することなしにデータを送受信できるAjaxの基幹技術である。
※フリー百科事典『ウィキペディア(Wikipedia)』より引用

個人理解ですが、“ページ遷移することなしに”というところが、ポイントの様です。先回投稿時にESPr® Developerで測定した温度データをPHPプログラムで表に加工しましたが、PHPはサーバー側で動くプログラムですので、データだけでなく、表の枠線等もサーバー側で生成して、ページの全内容を送ってきます。先回の表はシンプルですが、複雑なページの場合、時間が掛かってしまいます。一方で、JavaScript等を使用して、表の枠線等の情報を除き、データのみHTTP通信を使って受け取り、すでに受け取って表示されているブラウザー上の枠線の中のデータのみを変更するようにすることで、通信時間を短縮できる利点がある様です。

今回、HTTP通信の確認を行う理由について説明します。サーバー上のSQLiteファイルに書き込まれている温度データを取得して、ブラウザー上のグラフに表示する為に “Chart.js” というJavaScriptライブラリを使用しようと思っています。JavaScriptはブラウザー上で動きますので、サーバー上にあるデータを何らかの方法で取得する必要があります。そこで前準備として、XMLHttpRequest  APIを使ってサーバー上のデータを取得する方法について確認しておきます。
ブラウザー上にグラフを表示する方法は、ネット検索し他にも幾つか ありましたが、フリーで比較的関連記事の多かった“Chart.js” を使ってみることにしました。当初はデータ通信の必要のないPHPライブラリ等を探していたのですが、先に書いたように速度等の関連でもともとの記事が少ないのか、JavaScriptライブラリがほとんどで、PHPライブラリについてはネットでうまく検索 することが出来ませんでした。
ただ、本記事作成時に改めて本などを確認すると、“JpGraph”、 “Libchart”、 “pChart” 等のライブラリがある様ですので、使えるようであれば、いつか紹介してみたいと思います。

HttpRequest  確認プログラム

(1)概要
今回作成したXMLHttpRequest  APIを使った確認プログラムを紹介します。リンクを開くと下記の様な画面がブラウザーに出力され、[Quiz]に回答すると、下の図の通り‘正解’,‘不正解’によってコメント,背景色を変えて表示します。また、下の「詳細情報表示」ボタンをクリックすると最初は何も表示されていませんが、ヤリキレナイ側の名前の由来を表示します。「クリア」ボタンを押すと表示を初期化します。

(2)ブラウザー側のプログラム(HTML+JavaScript)
ボタン等の画面全体をHTMLの<body></body>(行番86~107)内で記載しています。行番90~93の<input>タグでは、onClick属性でクリック時に呼び出すJavaScriptの関数名を設定しています。これらのボタンがクリックされるとJavaScriptで書かれた関数 “exec_svr_prg” (行番25~42)を呼び出します。行番28でどのボタンが押されたのか識別する為の引数の値を変数に格納し、行番29では、XMLHttpRequest  APIを有効にするための関数 “createXmlHttpRequest” を呼び出します。行番31では、サーバー側のPHPプログラムを指定し、行番32~34でデータ送信(ボタンのValueの値を送信)、行番35でPHPの処理結果を受け取り、行番37で受け取った値をテキストエリアに表示します。行番38では関数を呼び出し、関数の中でPHPの処理結果に応じて、テキストエリアの文字色と背景色を変更する処理を行っています。
行番102はサーバー上のテキストファイルを受け取る関数を呼び出し、行番103は画面を初期化する関数を呼び出しています。
テキストファイルを受け取る関数(行番58~73)では、サーバー上にあるテキストファイルの内容を取得し、ブラウザー上に表示する処理を行っています。

<!DOCTYPE html>
<html lang="ja">

<head>
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta charset="UTF-8">
<title>HTTP通信テスト</title>
    <script type="text/javascript">

	// HTTP通信API設定
	function createXmlHttpRequest(){
    	    var xmlhttp=null;
    	    if(window.ActiveXObject){
        	try { xmlhttp=new ActiveXObject("Msxml2.XMLHTTP"); }
        	catch(e) { try { xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); }
            		   catch (e2){ }
                }
    	    }else if(window.XMLHttpRequest){
        	xmlhttp = new XMLHttpRequest();
    	    }
    	    return xmlhttp;
	}

	// サーバー側PHPプログラムを起動し、結果を得る
	function exec_svr_prg(rcv_dat)
	{   document.getElementById("rtn_msg").value = "" ;

	    var get_dat = rcv_dat.value ;
            var xmlhttp=createXmlHttpRequest();
            if(xmlhttp!=null){
        	xmlhttp.open("POST", "http_test.php", false);
        	xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
        	var data = "data="+get_dat;
        	xmlhttp.send(data);
        	var rtn=xmlhttp.responseText;
		//alert("HTTPデータ受信:" + rtn );
        	document.getElementById("rtn_msg").value = rtn ;
		chgColor(rtn) ;
	    }else{
		alert("HTTP通信API設定失敗!");
    	    }
	}

	// 文字表示領域の色を変える
	function chgColor(arg) {
	    document.getElementById("rtn_msg").style.fontWeight = "bold";

            if (arg.indexOf('不正解') != -1) {
            	document.getElementById("rtn_msg").style.color = "yellow";
		document.getElementById("rtn_msg").style.backgroundColor = "red";
            } else {
            	document.getElementById("rtn_msg").style.color = "blue";
		document.getElementById("rtn_msg").style.backgroundColor = "ivory";
            }
        }

	// ファイル内容を取得する取得
	function getTxtInf() {
	    document.getElementById("txt_inf").innerText = "";
      	    var xmlhttp = createXmlHttpRequest();

      	    xmlhttp.onreadystatechange = function() {
                if (xmlhttp.readyState == 4) {
        	    if (xmlhttp.status == 200) { 
            		document.getElementById("txt_inf").innerText = xmlhttp.responseText;
          	    } else {
            		alert("ERROR : " + xmlhttp.status);
          	    }
                }
      	    }
      	    xmlhttp.open("GET", "dat_tmp.txt");
      	    xmlhttp.send();
    	}

	// ファイル内容を取得する取得
	function All_Clear() {
	    document.getElementById("txt_inf").innerText = "";
	    document.getElementById("rtn_msg").value = "" ;
	    document.getElementById("rtn_msg").style.backgroundColor = "white";
	}

    </script>
</head>


<body>

    <P>[Quiz] 実際に北海道にある川は?</P>
    <form>
    <input type="button" name="btnA" id="btn_A" onClick="exec_svr_prg(this);" value="A.イトオシイ川">
    <input type="button" name="btnB" id="btn_B" onClick="exec_svr_prg(this);" value="B.クルオシイ川">
    <input type="button" name="btnC" id="btn_C" onClick="exec_svr_prg(this);" value="C.ヤリキレナイ川">
    <input type="button" name="btnD" id="btn_D" onClick="exec_svr_prg(this);" value="D.モノサミシイ川">
    </form>
    <BR>
    <TEXTAREA id="rtn_msg" style="width:465px;height:50px;" wrap="off"></TEXTAREA>
    <div>出題参考 : http://omnamahashivaya.info/archives/1718.html</div>
    <div>出題参考 : https://www.travel.co.jp/guide/article/21776/</div>

    <BR><BR>
    <form>
    <input type="button" name="getTxt" id="get_Txt" onClick="getTxtInf();" value="詳細情報表示">
    <input type="button" name="clrTxt" id="clr_Txt" onClick="All_Clear();" value="クリア">
    <form>
    <div id="txt_inf"></div>

</body>
</html>

テキストファイルを受け取る関数(行番58~73)で呼び出すテキストファイルには下記が記載され、サーバー上保管されています。

ヤリキレナイ川は北海道に実在し、アイヌ語で
「ヤンケ・ナイ(魚の住まない川)」などが語
源と言われている様です。

(3)サーバー側プログラム(PHP)
次にPHPプログラムの説明を行います。行番6では、JavaScriptから、送られたデータを受け取ります。この値は[Quiz]の回答ボタンのValueの値ですので、最初の1文字目はそれぞれ “A” ,“B” ,“C” ,“D” となっています。そこで行番7で受け取ったデータの最初の1文字目を取得し、行番9~19の判定処理でクリックされたボタンに対応するコメントを変数に設定し、行番20で返信しまています。

<?php
error_reporting(0);
mb_language("ja");
mb_internal_encoding("UTF-8");

$rcv_dat=$_POST["data"];
$ck_chr=mb_substr($rcv_dat,0,1);

if($ck_chr=="A"){
	$msg="不正解です。(選択:A) バッカじゃない!";
}else if($ck_chr=="B"){
	$msg="不正解です。(選択:B) もっと勉強して下さい。";
}else if($ck_chr=="C"){
	$msg="正解です!(選択:C) すごい!あなたは優秀です。";
}else if($ck_chr=="D"){
	$msg="不正解です。(選択:D) もの寂しい気持ちです。";
}else{
	$msg="予期せぬ回答です。";
}
echo $msg;
?>

まとめ

前段でPHPライブラリ等を探していたことを書きましたが、結果的にはJavaScriptライブラリしか見つけられなかったことによって、このXMLHttpRequest  APIの使いかたについて少しでも理解を深められたことは良かったと思います。
HTML,JavaScript,CSS,PHPなど、単独でもわからないことばかりなのに、一つの処理に複数混在すると非常に困惑してしまいますが、今回のHTTP通信は他の用途でも今後使用すると思いますので、細かな設定方法なども確認しておきたいと思います。

★今回の成果★ ※リンクしています。
XMLHttpRequest  APIを使った確認プログラム

※サーバー環境:レンタルサーバー(ロリポップ)
ライトプラン(月々250円~)