Принудительное кеширование
Метки: [без меток]
Пишу приложение, которое должно работать с некоторыми данными, вытаскиваемыми с удаленного хоста. Данные представляю собой xml-документы, причем каждый из них содержит поле cachedUntil. Поскольку очень нежелательно запрашивать данные чаще, чем положено (в частности, пока не истечет указанное время), нужно самостоятельно кешировать эти документы.
Наиболее очевидный способ, как мне кажется, это выставлять ExpirationTime для каждой CacheEntry. Сейчас код выглядит примерно так:
req.open('POST', url, false);
req.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
req.send(poststring);
var cache_descr = this.cache_session.openCacheEntry(url, Ci.nsICache.ACCESS_WRITE, true);
var cached_until = evaluateXPath(req.responseXML, "/eveapi/cachedUntil/text()")[0].data; // Выцепить нужный кусок
var d = cached_until.split(/ |:|-/); // Строка вида "2009-07-18 22:54:58"
cache_descr.setExpirationTime(Date.UTC(d[0], d[1]-1, d[2], d[3], d[4], d[5])/1000); // месяц нужно уменьшить на 1
cache_descr.storagePolicy = Ci.nsICache.STORE_ON_DISK;
var file = cache_descr.file;
dump(file.path+"\n");
dump(file.exists() ? "Yeah\n": "Nah\n");
Выдает результат вида
/home/aragaer/.aragaer/jaet/l7jyr6m4.default/Cache/BCE768DEd02 Nah
При этом, ничего не кешируется. ngrep показывает, что каждый раз происходит обращение к серверу.
Спрашивается: что я делаю не так?
Понял, что "не так".
В nsHttpChannel имеются следующие строки:
1445 // If the post id is already set then this is an attempt to replay 1446 // a post transaction via the cache. Otherwise, we need a unique 1447 // post id for this transaction. 1448 if (mPostID == 0) 1449 mPostID = gHttpHandler->GenerateUniqueID();
Теперь вопрос в том, как это правильно обойти.
Надеяться на то, что XMLHttpRequest сумеет вытащить результат POST-запроса из кэша, было неправильно. Руками создавать канал, которому явно указывать кэш, который нужно использовать - вроде получилось, но слишком громоздко и не до конца работает. В итоге я просто самостоятельно проверяю наличие и валидность CacheEntry с нужными мне данными, и если нужно, запрашивать новые (тем же XMLHttpRequest-ом), после чего прописывать expirationTime в соответствии с тем, что указано внутри документа.
![[logo]](/site/images/logo.jpg)