「JavaScript/XMLHttpRequest」の版間の差分

削除された内容 追加された内容
Ef3 (トーク | 投稿記録)
Fix typo; s/readstatus/readyStatus/7i
タグ: 2017年版ソースエディター
Ef3 (トーク | 投稿記録)
→‎サンプルコードおよび前提の解説: 完全なHTML5に書き直し。
タグ: 2017年版ソースエディター
15 行
とりあえず、サーバの設定や構成の準備がうまく行ってるかどうかを、次のコードで試してみよう。下記プログラムは、XMLHttpRequestの動作確認用のプログラムである。(本来なら動作確認のほかに、サーバとのデータ送受信などを行いたいのだが、コードが長くなるので、今回はまだ動作確認だけにしている。)
 
ただし、アクセス先のテキストファイルとして aisatuhello.txt を test.html と同じディレクトリに用意してもらいたい(あいさつテキストの意味)
今後の作業のため、aisatuhello.txt には「helloHello world!」とでも書いておく(単にテキストファイルや画像を読み込むだけなら HTML の通常の機能でも可能だが、今回は動作確認なので、そのような単純な事例にしている
なお、実用の場合には サーバのPHPプログラム(rubyなど別言語でも構わない)と、もっと複雑な通信をしたりするだろう。)
 
;test.html:<syntaxhighlight lang="html5" line>
さて、ともかく動作確認のために下記コードを test.html という名前で保存してほしい。
<!DOCTYPE html>
<html>
<head>
<title>XMLHttpRequest</title>
<script>
const req = new XMLHttpRequest();
req.responseType = 'text';
 
const ReadyStateStrings = []
そして、test.htmlをwebサーバのドキュメントルートにアップロードしておくこと。
for (const property in XMLHttpRequest) {
 
ReadyStateStrings[XMLHttpRequest[property]] = property
それができたら、下記コードを、webサーバを介してwebブラウザでアクセスしよう。
}
 
console.log(ReadyStateStrings)
なお、下記コードで alert させているのは、通信途中の動作確認もしたいためである。
var start = Date.now()
 
for (const event in ["loadstart", "load", "loadend", "error", "abort", "timeout"]) {
;コード test.html (これは htmlファイル)
req.addEventListener(event, ev => document.body.innerHTML += `<div>${Date.now() - start}(ms): event: ${event}<\/div>`)
<syntaxhighlight lang="javascript">
}
<script>
req.addEventListener("readystatechange", (ev) => {
var flag=0; // デバッグ用に使った残骸
document.body.innerHTML += `<div>${Date.now() - start}(ms): status = ${req.status}, readyState = ${ReadyStateStrings[req.readyState]}<\/div>`
 
var xhr = new XMLHttpRequest();
xhr.responseType = 'text' ;
 
xhr.onreadystatechange = function(){
if (xhr.status === 0){
//document.write("0 toutatu<br>"); // 0に到達
}
if (xhr.status === 200){
document.write("200 toutatu<br>");
}
if (xhr.status === 404){
document.write("404 status<br>");
}
if (xhr.readyState === 0 ){
document.write("read is 0<br>");
}
if (xhr.readyState === 1 ){
document.write("read is 1<br>");
flag =1;
alert("test1");
}
if (xhr.readyState === 2 ){
document.write("read is 2<br>");
flag =2;
alert("head2");
}
if (xhr.readyState === 3 ){
document.write("read is 3<br>");
flag =3;
//alert("Load3");
}
if (xhr.readyState === 4 ){
document.write("read is 4. Done!<br>");
document.write("status is " + xhr.status + " ! ");
// alert("DDD4"); // デバッグ用
}
if (xhr.readyState === 4 && xhr.status === 0 ){
alert("fault."); // 失敗
}
if (xhr.readyState === 4 && xhr.status === 200 ){
alert("Great! reach4 and State 200 tassei.");// 4に到達。 200 state を達成
document.write("<br>" + xhr.responseText + "<br>");
}
// document.write("uytre"); // デバッグ用
} ;
//xhr.open('GET', 'http://localhost/aisatu.txt', true); // 下でうまくいかない場合はこれで試す
xhr.open('GET', '/aisatu.txt');
//xhr.open('GET', 'husei'); // 意図的に失敗したい場合に使う。
 
xhr.send(null);
</script>
 
if (req.readyState === 4 && req.status === 200) {
document.body.innerHTML += `<div>${Date.now() - start}(ms): hello.txt => ${req.responseText}<\/div>`
}
});
req.open('GET', './hello.txt');
req.send(null);
</script>
</head>
<body>
<h1>XMLHttpRequest</h1>
jjf // html読み込みをしてるかどうかの確認に使うための、無意味な文字列
</body>
</html>
 
</syntaxhighlight>
;実行結果(ブラウザ):<syntaxhighlight lang="html">
XMLHttpRequest
41(ms): status = 200, readyState = HEADERS_RECEIVED
41(ms): status = 200, readyState = LOADING
43(ms): status = 200, readyState = DONE
43(ms): hello.txt => Hello world!
</syntaxhighlight>
 
:※ なお、上コード中の「xhr」とは別に予約語ではなく、単なる変数名である。なので、「xhr」でなくとも他の変数名でも構わない。
 
さて、このコードに、webサーバを介してwebブラウザでアクセスしよう(再掲)。
 
もし、test.htmlというファイル名でローカルホストにアップロードしたなら、
[http://localhost/test.html http://localhost/test.html ]
というアドレスにブラウザでアクセスすることで、結果を見れる。
 
;表示結果
動作に成功している場合、alertボックスを何回かクリックして閉じたあと、最終的に下記のように表示される(なお alert の用途はここでは通信途中の確認用)。
 
<pre>
200 toutatu
read is 2
200 toutatu
read is 3
200 toutatu
read is 4. Done!
status is 200 !
Hello World!
</pre>
 
この「200」や「4」は、JavaScriptの規格で意味が決まっている数字である(技術的な解説については、のちのセクションで後述する)。
 
その規格の意味により、とりあえず上記の動作確認では「200」や「4」と表示されれば、成功である。
 
規格について抜粋的に説明すると、readyStateプロパティが4なら、すべての応答データを取得できている<ref>山田祥寛『JavaScript本格入門』、2019年8月17日 初版 第6刷発行、P395</ref>という意味である。
 
なので、とりあえず、成功なら 4 が表示されているハズである。
 
また、「200」と言うのは直前のリクエストに対して「成功」という意味である。失敗なら、200以外のメッセージであり、たとえば「0」や「404」(リソースが存在しない場合)などである。
 
コードの技術的な解説については、のちのセクションで解説する。
 
最後の「Hello World! 」は、単にaisatu.txt から送られてきたデータを表示しているだけである。なので、もし aisatu.txt に別の文字列を書いておけば、それが表示される。(Fedora Linux 35 で実験した限りでは、aisatu.txt に書かれた文字列が日本語の文字列でも、正しく表示される。)
 
 
=== ミスの原因 ===