スキップしてメイン コンテンツに移動

些細な日常

JavaScriptのFetchで取得したデータをDocumentへ適合できるDOMParserの使い方

JavaScriptのプログラミングでサーバーを介したデータの受け渡し:Ajax通信を行う仕組みの一つにFetch APIがある。オブジェクトに最初からウェブの送受信の時間差の難点を克服するPromiseを想定して使えるのが特徴で、旧来のXMLHttpRequest APIと比べて便利に刷新された機能を有する。

しかし取得するデータがDocumentインターフェースに属さないのがちょっと使い辛い。

例えばfetch()メソッドでhtmlファイルのデータをtextで受け取ってもそこからHTMLを操作するのはUSVStringだから合わなくて全く不可能なのが厄介みたいな場合が出て来る。

Fetch APIはデータに特化して読み書きに純粋に注力するべく考案されているのか、少なくともhtmlファイルなどを一つのDOMツリーとして種々と操作するには却って旧来のXMLHttpRequestこそまだ便利だし、十分に使える状況なんだけれどもその他は不便なので、Fetch APIでも何とかならないかと望んでしまう。

DOMParserを使うとFetchのデータでもDocumentへ適合できる

幸いにも無理ではない。Fetchのデータにかぎらず、Documentへパース/解析して変換できる方法がJavaScriptにはあってDOMParserという。

使い方はとても簡単で、new演算子でコンストラクタ関数のオブジェクトを作成したらさらに引数にデータを入れたparseFromString()メソッドをかけてデータを受け取り直す。

DOMParserの使い方の見本のソースコード

var pso = new DOMParser();
var psd = pso.parseFromString(データ, "MINE type");

DOMParserのパースは三種類のファイルに対応している。

パースされるファイルとMINE typeの組み合わせ

xmlファイル/XMLDocument
application/xml
text/xml
svgファイル/SVGDocument
image/svg+xml
htmlファイル/HTMLDocument
text/html

xmlファイルの二つのMINE typeはRFCの技術仕様で、2014年から「どちらでもよい、が、application/xmlを推奨」(xmlのContent-Typeはapplication/xmlか、それともtext/xml?)と定められている。

Fetchで取得したデータをDOMParserで変換する方法

送受信されるBodyに特有のデータが幾つかあるけど、しかしHTMLなどのDocumentの記述/マークアップをそのままの仕方で持っているのはtextだけで、DOMParserで変換すれば直ぐにDOMツリーとして扱えるようになる。

htmlファイルのtextをHTMLDocumentへパースするサンプル

JavaScript

var url1 ="/";
fetch (url1).then ((response1) => response1.text()).then ((text) => {
var pso1 = new DOMParser();
var psd1 = pso1.parseFromString(text, "text/html");
var txh1 = psd1.querySelector("h1#blog-title").textContent;
var bt1 = document.createElement("p");
var lk1 = document.createElement("a");
lk1.setAttribute("href", url1);
lk1.textContent = txh1;
r1.appendChild(bt1.appendChild(lk1));
lk1.insertAdjacentHTML("afterend", "(トップページ)");
});

※変数の「r1」は実行結果を表示するための親要素のIDだ。

実行結果

トップページ(ルートドメインの「/」のURL)のhtmlファイルからブログ名(h1#blog-titleの文章)を取得してリンク(aタグ)と添え書きを付けて段落(pタグ)に表示している。

Fetchのtext()メソッドで取得したtextデータのhtmlファイルなどをセレクターで分けたりして操作したい場合には事前にDOMParserでパースして相応のDocumentへ変換しながら元のファイルのDOMツリーの状態に戻さないとプログラミングを受け付けない。

htmlファイルのReadableStreamをHTMLDocumentへパースするサンプル

もう一つReadableStreamでもDocumentを使うかも知れない。Fetch APIをStreams APIと組み合わせるとデータの読み込みと書き出しを漸次的に操作することができる。このとき、必要なデータの種別がReadableStreamになって他のデータでは動作しないんだ。

ReadableStreamはByteという数字の羅列だから通常の場合でも最終的にデコード/解読して使われるけれどもhtmlファイルなどはさらにパースするとDocumentとしても扱えるようになる。

JavaScript

var url2 ="/";
const dcd = new TextDecoder();
var btc = "";
fetch (url2).then ((response2) => response2.body.getReader()).then ((reader) => {
function chunk({done, value}) {
if (done) {
return;
}
btc += dcd.decode(value);
if (/<\/h1>/.test(btc)) {
var pso2 = new DOMParser();
var psd2 = pso2.parseFromString(btc, "text/html");
var txh2 = psd2.querySelector("h1#blog-title").textContent;
var bt2 = document.createElement("p");
var lk2 = document.createElement("a");
lk2.setAttribute("href", url2);
lk2.textContent = txh2;
r2.appendChild(bt2.appendChild(lk2));
lk2.insertAdjacentHTML("afterend", "(トップページ)");
return;
}
reader.read().then(chunk);
}
reader.read().then(chunk);
});

※変数の「r2」は実行結果を表示するための親要素のIDだ。

実行結果

トップページ(ルートドメインの「/」のURL)のhtmlファイルからブログ名(h1#blog-titleの文章)を取得してリンク(aタグ)と添え書きを付けて段落(pタグ)に表示している。

FetchのBodyのbodyプロパティからgetReader()メソッドで取得したReadableStreamデータのhtmlファイルなどをセレクターで分けたりして操作したい場合、先ずはTextDecoderで文字コードをByteからデコードしなくてはならない。TextDecoderの使い方はnew演算子でコンストラクタを作成する。引数に半角引用符付きで文字コードを入力するけれども空白だと初期値の「UTF-8」へデコードされる。次いでtextデータのときと同じようにDOMParserでパースする。TextDecoderでデコードしてもReadableStreamデータはDOMStringに変わるだけなので、相応のDocumentへ変換しながら元のファイルのDOMツリーの状態に戻さないと所定のプログラミングを受け付けない。

コメント

最近の投稿

日付: 

コドリンガの悪魔の害虫と呼ばれる農業破壊の脅威

イメージ

人気の投稿

宜保愛子は本物の霊能力者だと考えられる三つの真実

イメージ

昭和から平成にかけてテレビや雑誌で何度も大きく取り上げられて物凄く活躍した霊能力者の 宜保愛子 がいた。何気なく昔のテレビ番組を観ていたら霊視は嘘だったと思えない内容で、本当にびっくりした。昔、そんなに引き付けられて観ていたわけではないし、改めて霊能力が本当かどうかを確かめようと...

平田監督の白井球審の誤審への抗議はパワハラへの強力な対処法に他ならない

イメージ

日本プロ野球で 佐々木朗希が完全試合を実現して 次の試合も八回まで無安打と無失点の状況で、次の試合はどうかと注目した4月24日の対オリックスバファローズ戦は初回の先頭打者の初球にヒットを打たれて五回に二失点を喫して連続の無安打と無失点が両方とも途絶えてしまった。 しかし予想外...

伊良部秀輝が自殺した原因はミッドライフクライシスによる鬱と飲酒だと考える

イメージ

プロ野球選手の 伊良部秀輝 が自殺したと知ってショックを受けたことがあった。もう十年以上前になる。2011年の夏、享年四十二と早過ぎたのに加えて大好きな投手の一人だったので、とても残念に感じた。 目次 伊良部秀輝が大好きだった記憶 負けても自分のスタイルを貫き通した 野球への...