JavaScript/XMLHttpRequest
XMLHttpRequest (XHR) とは、ウェブサーバと通信を行うためのJavaScriptのオブジェクトです。
fetch API
編集Ajax/XMLHttpRequestは、古くから使われている技術ですが、すでにAjax/XMLHttpRequestの欠点や問題点を解消した fetch API がモダンブラウザに実装されているので、新しく覚えるあるいは新規にコードを起こす場合は、Ajax/XMLHttpRequestではなく、 fetch APIを使うべきです。
fetch APIを使うと、下記のようなawait async promiseを使って非同期な並行・並列処理をメソッドチェインで簡素に表現できます。
- fetch.html
<!DOCTYPE html> <html> <head> <title>fetch API</title> <script> fetch('./hello.txt') .then(response => response.text()) .then(data => document.body.innerHTML += `<div>${data}<\/div>`) </script> </head> <body> <h1>XMLHttpRequest</h1> </body> </html>
Ajax
編集CGIなどの仕組みを使ってサーバからデータを取得するにはウェブページを遷移する必要がありますが、XMLHttpRequestを用いるとページの遷移なしに、動的かつ非同期にデータを取得することができます。このような技術はAjax (asynchronous JavaScript and XML) と呼ばれます。Ajaxを駆使するとJavaScriptを用いてGoogle マップのようなインタラクティブなウェブアプリケーションを構築することができます。
XMLHttpRequestはその名に反してXMLドキュメントでないデータもやり取りすることができます。また、HTTP以外にFTP通信も行うことができます[1](ローカルホストではローカルファイルも取得可能)。ただし、XMLHttpRequestを用いて通信できるのは同じドメインのサーバに限られるため、外部のサーバと通信をすることはできません。これを同一生成元ポリシー(どういつせいせいもとポリシー、same origin policy)といいます。
XMLHttpRequest
編集- イベントリスナーによるイベントハンドリング
const req = new XMLHttpRequest(); req.addEventListener("progress", (ev) => { if (ev.lengthComputable) { const percent = ev.loaded / ev.total * 100; // 進捗表示 console.log("${percent}%転送しました。") } else { // 長さ不明 console.log("転送中。") } }); req.addEventListener("loadstart", (ev) => console.log("転送を開始しました。")); req.addEventListener("load", (ev) => console.log("転送しました。")); req.addEventListener("loadend", (ev) => console.log("転送が終了しました。")); req.addEventListener("error", (ev) => console.log("ファイルの転送中にエラーが発生しました。")); req.addEventListener("abort", (ev) => console.log("ユーザーが転送をキャンセルしました。")); req.addEventListener("timeout", (ev) => console.log("転送がタイムアウトしました。")); req.addEventListener("readystatechange", (ev) => { switch (req.readyState) { case XMLHttpRequest.UNSENT: console.log("UNSENT"); break; case XMLHttpRequest.OPENED: console.log("OPENED"); break; case XMLHttpRequest.HEADERS_RECEIVED: console.log("HEADERS_RECEIVED"); break; case XMLHttpRequest.LOADIND: console.log("LOADIND"); break; case XMLHttpRequest.DONE: const status = req.status; if (status === 0 || (status >= 200 && status < 400)) { console.log(req.responseText); } else { console.log(req.responseXML); console.log(req.responseText); } break; default : console.log(`${req.readyState} は仕様にないXMLHttpRequest.readyState`); } }); req.open('GET', './example.xml', false); req.send(null);
- ※ イベントリスナーは open() を呼び出す前に追加する必要があります(もし、そうしないのであれば progress イベントは発火しません)。
資料
編集XMLHttpRequestの静的プロパティ
編集- XMLHttpRequest.UNSENT
- 0 : number
- XMLHttpRequest.OPENED
- 1 : number
- XMLHttpRequest.HEADERS_RECEIVED
- 2 : number
- XMLHttpRequest.LOADING
- 3 : number
- XMLHttpRequest.DONE
- 4 : number
- XMLHttpRequest.arguments
- null : object
- XMLHttpRequest.caller
- null : object
- XMLHttpRequest.length
- 0 : number
- XMLHttpRequest.name
- "XMLHttpRequest" : string
XMLHttpRequestのインスタンスプロパティ
編集- XMLHttpRequest.prototype.DONE
- XMLHttpRequest.prototype.HEADERS_RECEIVED
- XMLHttpRequest.prototype.LOADING
- XMLHttpRequest.prototype.OPENED
- XMLHttpRequest.prototype.UNSENT
- XMLHttpRequest.prototype.abort
- XMLHttpRequest.prototype.constructor()
- XMLHttpRequest.prototype.getAllResponseHeaders
- XMLHttpRequest.prototype.getResponseHeader
- XMLHttpRequest.prototype.onreadystatechange
- XMLHttpRequest.prototype.open
- XMLHttpRequest.prototype.overrideMimeType
- XMLHttpRequest.prototype.readyState
- XMLHttpRequest.prototype.response
- XMLHttpRequest.prototype.responseText
- XMLHttpRequest.prototype.responseType
- XMLHttpRequest.prototype.responseURL
- XMLHttpRequest.prototype.responseXML
- XMLHttpRequest.prototype.send
- XMLHttpRequest.prototype.setRequestHeader
- XMLHttpRequest.prototype.status
- XMLHttpRequest.prototype.statusText
- XMLHttpRequest.prototype.timeout
- XMLHttpRequest.prototype.upload
- XMLHttpRequest.prototype.withCredentials
脚注
編集- ^ 2021年6月の時点でディフォルトでFTPスキームを(かつてのgopherのように)無効にするブラウザが増えつつある。https://blog.chromium.org/2020/09/chrome-86-improved-focus-highlighting.html