XMLHttpRequestクラスとそのインスタンス
簡単に言えば,インタラクティブに他のページや画像などを持ってきて,今のページに表示させるためのクラスである.
Promiseクラスのオブジェクトを生成するように設計してやると,「読み込み終わって,結果が正しい時に,次のコードを実行する」という処理ができる.
Cross-Originポリシーの関係で,XMLHttpRequestクラスのインスタンスは,そのJavaScriptファイルが置いてあるドメインからしかAjaxできない.(正確には色々やればできるが面倒臭い)
コード例
htmlを取得して,その結果をテキストとしてdivに表示する.
Cross-Originポリシーの関係で,XMLHttpRequestクラスのオブジェクトは,そのJavaScriptファイルが置いてあるドメインからしかAjaxできない.(できるが面倒臭い)
<!DOCTYPE html>
<!-- PromiseAjaxWithClass.html -->
<html lang="ja">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta charset="utf-8">
<title>Promiseを使ってAjax</title>
<script type="text/javascript" src="./PromiseAjaxWithClass.js">
</script>
</head>
<body>
<p>取得したいHTMLのURLを記入</p>
<form>
<input type="text" name="target_url" value="http://cad.lolipop.jp/" />
<input type="button" name="send_button" value="取得" onclick="getHtml(this.form.elements['target_url'].value)" />
</form>
<div id="display_iframe">
ここに取得してきたものが表示されます.
</div>
</body>
</html>
// PromiseAjaxWithClass.js
'use strict';
class MyAjax{
constructor(targetUrl){
this.targetUrl = targetUrl;
this.gottenHtmlPage = '';
}
setTargetUrl(targetUrl){
this.targetUrl = targetUrl;
}
setDisplayingDivId(divId){
this.divId = divId;
}
// AjaxによるHTMLページの取得を実行する関数 Promiseを返す
startHttpRequest(){
return new Promise((resolve, reject) => {
let xmlHttpRequest = new XMLHttpRequest();
//open(HTTPメソッド, URL, 非同期モードかどうか, ユーザ名, パスワード)
xmlHttpRequest.open('GET', this.targetUrl, true);
xmlHttpRequest.onload = () => {
if(xmlHttpRequest.status >= 200 &&
xmlHttpRequest.status < 300){
resolve(xmlHttpRequest.responseText);
}
else{
reject(xmlHttpRequest.status);
}
};
xmlHttpRequest.onerror = () => {
reject(xmlHttpRequest.status);
};
//設定が終わった後にsend(null)を実行すると取得が始まる.
xmlHttpRequest.send(null);
});
}
// AjaxによるHTMLページの取得が完了した時に呼び出すコールバック関数
whenFinishSuceed(result){
document.getElementById('display_iframe').innerText = result;
}
whenFinishFailed(err){
document.getElementById('display_iframe').innerHTML =
'<p>' + 'Faild to get WebPage. Error code is: ' + err + '</p>';
}
}
window.getHtml = (targetUrl) => {
window.myAjax.setTargetUrl(targetUrl);
window.myAjax.startHttpRequest()
.then(window.myAjax.whenFinishSuceed)
.catch(window.myAjax.whenFinishFailed);
};
window.addEventListener('load', () => {
window.myAjax = new MyAjax('http://cad.lolipop.jp/');
window.myAjax.setDisplayingDivId('display_iframe');
window.myAjax.startHttpRequest()
.then(window.myAjax.whenFinishSuceed)
.catch(window.myAjax.whenFinishFailed);
});
fetch API
とまぁ,自分で実装すると面倒臭いことこの上ないのだが,Promiseのインスタンス(オブジェクト)を返す全く同じ機能がfetch
関数として既に標準ライブラリとして実装されており,Chromeでは問題なくXMLHttpRequestクラスの代わりとして使用できる.
おまけに,Cross-Originポリシーも(サーバが対応していれば)一行設定を書いてやるだけで無視することができる.
コード例
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8" />
<title>Fetch API Test</title>
<script type="text/javascript">
window.addEventListener('load', () => {
fetch('http://cad.lolipop.jp/', { // 取得するデータのURL
method: 'GET',
mode: 'cors', //Cross-Originポリシーを無視する
credentials: 'same-origin' // 認証がある時はこのオプションを指定
}).then((response) => {
return response.text()
}).then((text) => {
document.getElementById('for_display').innerText = text;
}).catch((error) => {
console.log(error);
});
});
</script>
</head>
<body>
<div id="for_display">
</div>
</body>
</html>