QA@IT

Google Chrome拡張機能のコンテントスクリプトから、XMLHttpRequestで自身の元ソースを取得しようとするがうまくいかない。

2401 PV

実現したい内容としては、以下の様な流れを想定しています。

1.htmlファイルなどのWebページ開発をローカルでしている
2.そのローカルファイルをChromeで開いておく
3.自身のソースコードをXMLHttpRequestで定期的に取得する
4.もしソースに変化がなければそのまま。ソースに変化があればリロード

つまり、エディタ上でファイルを編集しているとき、ブラウザにフォーカスを移してリロードして修正がうまくいったか確かめてまたエディタに戻る…、という過程をなくすことが目的です。
エディタ上で編集をしているだけで、ブラウザで表示しているそのローカルファイルが更新してくれる環境を期待しています。

しかし、XMLHttpRequestで定期的にソースを取得するときにうまくいきません。
全くソースを取得できていないのではなく、ソースは取得できるのですが、ローカルHTMLファイルに変更を加えても取得されるXMLHttpRequestに変化がありません。
ソースは以下の通りです。Chrome拡張のコンテントスクリプトで以下のJavaScriptを実行させています。

var source = null;
var xhr;
(function request() {
  xhr = new XMLHttpRequest();
  xhr.open("GET", location.href, true);
  xhr.send();
  xhr.onreadystatechange = function() {
    if (xhr.readyState == 4) {
      if (!source || source == xhr.responseText) {
        source = xhr.responseText;
        console.log(source); // 取得したソースのチェック用
        setTimeout(request, 1000);
      } else {
        location.reload(true);
      }
    }
  }
})();

また、拡張機能のmanifest.jsonでは、"content_scripts" の "matches" に "file:///" をしており、"permissions" には、"file:///" を指定しています。

console.log(source) で取得したソースを確認すると、ローカルファイルに変化を加えた場合でも毎度同じ値になってしまっています。

挙動としてさらに意味がわからなく思っていることがあります。
対象のローカルファイルに変更を加え、仮にブラウザで開いているローカルファイルを手動でリロードすると、当然ブラウザの表示に変更されます。
一方、コンソールに表示される先の値にはリロード前と比較して変化がないままなのです。
いったいどこからXMLHttpRequestでソースを取得してきているのかと疑問を感じています。

そして、ブラウザで開いているそのローカルファイルを、一度閉じて再び開き直すと、今度はコンソールに表示される結果にも変更された内容が反映されているという挙動でした。

どうすれば正しくローカルファイルのソースを取得できるでしょうか。
よろしくお願いします。

  • なるほど。
    キャッシュの可能性は自分で考えていましたが、タイムスタンプをパラメータで指定する方法があるのですね。
    教えていただいた方法で期待通りの動作が実現できました。
    また一つ勉強になりました。ありがとうございます。
    -

回答

キャッシュを見てしまっている可能性が高そうですね。
そういった場合、タイムスタンプなどをパラメータとして追加して、強制的に新しいファイルとして取得する方法が定番テクニックです。

xhr.open("GET", location.href + '?' + (new Date().getTime()), true);
編集 履歴 (0)
ウォッチ

この質問への回答やコメントをメールでお知らせします。