2012年7月22日日曜日

Cache Manifest使用時のXMLHttpRequest



Cache Manifestを使用したオフラインアプリでもXMLHttpRequestを使用することができます。次のような点に注意すれば、XMLHttpRequestを利用してCacheを残しつつ、オンライン時に一部のデータだけ更新することができます。
以下の方法はSafari/iOSでのみチェックしています。

1.Cache Manifestの設定
次の設定をCache Manifestに含める。
NETWORK:
*
これを設定しないと、Cacheが有効なときはXMLHttpRequestのレスポンスが空となります。

2.XMLHttpRequeststatusのstatus=0チェック
Cacheが有効なときはXMLHttpRequeststatusのstatusコードが0となり、レスポンスが空になります。
ただし、XMLHttpRequeststatusのQuery StringがついたURLの場合、ホーム画面のアイコンからアクセスする場合はstatus=0ですが、Safariのアドレスバーからアクセスするとstatus=200となり、レスポンスはCacheされているデータとなります。

3.localStroageとの併用がお勧め
status=0のときにネットワークから取得したデータを使うことができるようにするため、XMLHttpRequeststatusで取得したデータはlocalStroageに保存しておくのがお勧めです。

XMLHttpRequest実装例

XmlReq = function(url) {
  this.url = url;
}

//elm = responseのcontentをセットする要素。
XmlReq.prototype.send = function(elm) {
  var req = this.createHttpRequest();
  req.open("GET", this.url, true); //true = 非同期。
  req.onreadystatechange =
    function() { //受信時に起動するイベントハンドラ
      if (req.readyState == 4) { //4 = 受信完了 (サーバ処理終了)
        var content = null;
        if (req.status == 200) {
          content = req.responseText;
          localStorage["content"] = content;
        } if (req.status == 0) {
          content = localStorage["content"];
        }
        if (content != null) {
          if (elm.tagName == "INPUT") {
            elm.value = content;
          } else if (elm.tagName == "DIV") {
            elm.innerText = content;
          } else {
            //適宜追加
          }
        }
      }
    };
  req.send(null);
}

XmlReq.prototype.createHttpRequest = function() {
  if(window.ActiveXObject){ //Win IE
    try {
      return new ActiveXObject("Msxml2.XMLHTTP");
    } catch(e) { //MSXML2以前
      return null;
    }
  } else if(window.XMLHttpRequest){
    //Win ie以外のXMLHttpRequestオブジェクト実装ブラウザ用
    return new XMLHttpRequest();
  } else {
    logDiv.innerHTML += "<br><null>";
    return null;
  }
}

XmlReq.prototype.toString = function() {
  return this.url;
}

XmlReqの利用例

function sendRequest() {
  var ID = new Date().getTime();
  var req = new XmlReq("http://" + location.host + "/SampleApp/Resources/data.txt?ID=" + ID);
  req.send(hiddenField);
}
function showData() {
  alert(hiddenField.value);
}

<input type="hidden" id="hiddenField">

0 件のコメント: