Serviceworker(PWA)とajaxは一緒に使えるのか?
やりたいこと
- ajaxで取得したデータをサービスワーカー内にキャッシュさせて、オフラインでも表示できるようにしたい。
問題
- ajaxだとサービスワーカー内にデータを保持できない。
- キャッシュ対象の中にajaxで取得していたjsonファイルやtxtファイルを書いてみたが、Serviceworker内には保持されていなかった。
解決案
- 色々試したがajax($getJsonとか)の取得方法だとダメ。
- デベロッパーツールのネットワークタブ> XHRを見るとXHRかFetchで取得したリソースが並んでいる。どうやら他のリソースをみたところFetch形式で取得したものはServiceworker内にキャッシュされているよう。
- なんかServiceworkerでfetchという言葉を聞いたことがある。
XHRからfetchで取得する方法に変えたらイケそう。
そもそもXMLHttpRequest、Fetch、$.ajaxって何が違うの?
・非同期通信で、サーバー上のデータを取得する方法としてXMLHttpRequest、Fetch、$.ajaxがある
・fetchはPromiseオブジェクトを返す(thenとかで順番制御がしやすい、短く書ける)
・fetchはXHRからの代替を目指している?
・fetchは新しい技術なのでIEで動かない(Polyfillで実装可能 https://github.com/github/fetch)
実際に修正したコード例
参考: jQuery.getJSON()
参考のソースで例示します。
$.getJsonの場合
$.getJSON( "ajax/test.json", function( data ) {
var items = [];
$.each( data, function( key, val ) {
items.push( "<li id='" + key + "'>" + val + "</li>" );
});
$( "<ul/>", {
"class": "my-new-list",
html: items.join( "" )
}).appendTo( "body" );
});
fetchの場合
動かなかった例
function getJsonData() {
var req_bnr = new Request("ajax/test.json", {
method: "get"
});
fetch(req_bnr)
.then(function (json) {
var items = [];
$.each(data, function (key, val) {
items.push("<li id='" + key + "'>" + val + "</li>");
});
$("<ul/>", {
"class": "my-new-list",
html: items.join("")
}).appendTo("body");
})
}
どうやらjsonがリーダブルな形式(htmlに書き出したり)ではないようです。
該当箇所を和訳と解釈
最初に呼び出すthenでのresponseではリーダブルな形式でないため return response.json();のプロミスオブジェクトを解決。
二回目のthenで実際に使いたい形にする(htmlに書き出したり)[応答がネットワークエラーだけエラーとなるが、HTTP 404または500であってもfetch()から返されたPromiseはHTTPエラーステータスを拒否しない。]
[言い換えれば、呼び出しが失敗したとしても、fetch()はそれを成功のように扱います。]
参考元のコードを使用させて頂き修正。
// fetchAPI用 返されたBodyをjsonにしてPromise.resolve()する
var handleResponse = function (response) {
return response.json()
.then(function (json) {
if (response.ok) {
return json;
} else {
return Promise.reject(response);
}
});
};
function getJsonData() {
var req_bnr = new Request("ajax/test.json", {
method: "get"
});
fetch(req_bnr)
.then(handleResponse)
.then(function (json) {
var items = [];
$.each(data, function (key, val) {
items.push("<li id='" + key + "'>" + val + "</li>");
});
$("<ul/>", {
"class": "my-new-list",
html: items.join("")
}).appendTo("body");
})
}
これを本番ページ向けに修正させたところ、オフラインでもjsonファイルが取得できました!
もともとTypeの列でXHRとなっていましたが、今回の修正でfetch形式で取得できるようになりました。
サービスワーカー内でXHRやajaxは動かないがfetchAPIが動く理由の考察(自論)
参考:Using the Cache API
参考: ServiceWorkerとCache APIを使ってオフラインでも動くWebアプリを作る
参考を読んで何となく解釈すると、
- fetchAPIだけでなく fetchAPI × cacheAPI(サービスワーカー内で動く)によるもの
- サービスワーカーjs内のファイル指定(cacheAPIの書き方)
- リソースをFetch APIでサーバーから取ってきてCache APIを使って保存しておき、Fetchイベントハンドラでキャッシュから取り出して返すということをしているらしい
ありがとうございました。
参考
Author And Source
この問題について(Serviceworker(PWA)とajaxは一緒に使えるのか?), 我々は、より多くの情報をここで見つけました https://qiita.com/yhrym/items/bf921ccad3a57da36749著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .