Google Maps では画面遷移のないシームレスな画像読み込みが行われます。
それにはAjaxと言われる最新技術が使われています。
Ajaxを使わないとシームレスな通信が不可能かと言われるとそうではありません。
今まではフレームを使ってシームレスな通信を行っていました。
実際に体験してもらった方が早いと思いますので以下のページをご覧ください。
Yahoo!検索 画面遷移無し(非同期通信) - フレームバージョン
このフレーム通信には、test2_1.html(親フレーム)、test2_1_sub.html(下フレーム)、test2_1_dummy.html(上フレーム(通信受信用、見えないフレーム))、test2_1.php(Web通信用)が使われています。
test2_1.html
<HTML><HEAD>
<META http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<TITLE>Yahoo!検索 画面遷移無し(非同期通信) - フレームバージョン</TITLE>
</HEAD>
<FRAMESET rows="0,*" frameborder="0" border="0" framespacing="0">
<FRAME src="test2_1_dummy.html" scrolling="NO" noresize marginwidth="0" marginheight="0" frameborder="0" name="up">
<FRAME src="test2_1_sub.html" frameborder="0" name="main">
<NOFRAMES>
<BODY>フレームが使用できないブラウザでは実行できません</BODY>
</NOFRAMES>
</FRAMESET>
</HTML>
rows="0,*"として見えないフレームを作る必要があります。
test2_1_sub.html
<HTML>
<BODY>
<SCRIPT language="JavaScript">
<!--
function get_data(){
parent.up.location.href = "test2_1.php?key="+document.fo.yahoo.value;
}
function set_data(html){
document.all("html_div").innerHTML = html;
}
//-->
</SCRIPT>
<FORM name="fo">Yahoo!検索<BR><INPUT size="20" type="text" name="yahoo"><INPUT type="button" value="検索" onclick="get_data();"></FORM>
<HR>
<DIV id="html_div"></DIV>
</BODY>
</HTML>
ここでget_data()は通信開始関数、set_data()は通信受信関数です。
parent.up.location.href =とすることで、見えない「上フレーム」を指定ページに移動させています。(ここでは検索用phpを起動します。)
Yahooの通信はWebページを簡単に取得できるPHPが使われています。
test2_1.php
<?php
$key = $_GET['key'];
$get_html_dat = file("http://search.yahoo.co.jp/search?p=$key");
$all_html_dat = "";
for($i=0;$i<count($get_html_dat);$i++){
if(!eregi("<li><div>",$get_html_dat[$i])){continue;}
$get_html_dat[$i] = ereg_replace('"', "", $get_html_dat[$i]);
$all_html_dat .= rtrim($get_html_dat[$i]);
}
echo "<HTML><BODY><SCRIPT>parent.main.set_data(\"$all_html_dat\");</SCRIPT></BODY></HTML>";
?>
PHPは、$get_html_dat = file(・・・);のたった一行で$get_html_datに配列としてWebページを取得できます。($get_html_dat[0]は一行目、$get_html_dat[1]には二行目・・と格納されています。)
また、結果を表示する際に、取得したデータをそのまま表示するのではなく、<li><div>がある行のみを表示し、存在しない行は飛ばします。
ereg_replace('"', "", $get_html_dat[$i]);では、JavaScriptエラーの原因となるダブルクォーテーション(")を変換しています。
最後にparent.main.set_data(\"$all_html_dat\");で、test2_1_sub.htmlのset_data()関数を引数(検索結果データ)込みで実行します。
そうすると画面に表示されるというわけです。
ちなみにtest2_1_dummy.htmlは何も書く必要はありません。(ダミーファイルです。)
さて、このようにフレームを用いた場合、ほとんどのブラウザで動作するという利点(携帯のフルブラウザでも可能です。たとえばこちら)がありますがデメリットとして、多くのファイルを用意する必要があり、煩わしいものとなっています。
そこでAjaxを使ってみましょう。サンプルを見てみるとわかりますが、動作はフレーム版とほぼ同じです。
Yahoo!検索 画面遷移無し(非同期通信) - Ajaxバージョン
この方法だと、test2_2.html(メインファイル、通信受信兼)、test2_2.php(Web通信用)と、とても少ないファイルで通信できます。
ちなみにAjax共通関数に関してはこちらを参照しました。
さて、内容を見ていきましょう。
test2_2.html
<HTML>
<BODY>
<SCRIPT language="JavaScript">
<!--
function get_data(){
httpObj = createXMLHttpRequest(set_data);
if(httpObj){
httpObj.open("GET","test2_2.php?key="+document.fo.yahoo.value,true);
httpObj.send(null);
}
}
function set_data(){
if((httpObj.readyState == 4) && (httpObj.status == 200)){
html = httpObj.responseText;
document.all("html_div").innerHTML = html;
}
}
// HTTP通信用、共通関数
function createXMLHttpRequest(cbFunc){
var XMLhttpObject = null;
try{
XMLhttpObject = new XMLHttpRequest();
}catch(e){
try{
XMLhttpObject = new ActiveXObject("Msxml2.XMLHTTP");
}catch(e){
try{
XMLhttpObject = new ActiveXObject("Microsoft.XMLHTTP");
}catch(e){
return null;
}
}
}
if (XMLhttpObject) XMLhttpObject.onreadystatechange = cbFunc;
return XMLhttpObject;
}
//-->
</SCRIPT>
<FORM name="fo">Yahoo!検索<BR><INPUT size="20" type="text" name="yahoo"><INPUT type="button" value="検索" onclick="get_data();"></FORM>
<HR>
<DIV id="html_div"></DIV>
</BODY>
</HTML>
createXMLHttpRequest(・・・);のカッコ内に受信後に実行される関数名を記述します。ここではset_dataを実行するようにしています。
httpObj.responseTextには受信データが入っています。後はtest2_1_sub.htmlとあまり変わりません。
test2_2.php
<?php
$key = $_GET['key'];
$get_html_dat = file("http://search.yahoo.co.jp/search?p=$key");
$all_html_dat = "";
for($i=0;$i<count($get_html_dat);$i++){
if(!eregi("<li><div>",$get_html_dat[$i])){continue;}
$get_html_dat[$i] = mb_convert_encoding($get_html_dat[$i],"UTF-8","auto");
$all_html_dat .= $get_html_dat[$i];
}
echo $all_html_dat;
?>
mb_convert_encoding($get_html_dat[$i],"UTF-8","auto");
で、文字コードをUTF-8に変換します。そうしないと文字化けします。
今回はダブルクォーテーションを変換したり、最後の出力を<SCRIPT></SCRIPT>で囲む必要はありません。
このように二通り試しましたが、あなたならどちらを使いますか?
