Это, вероятно, проблема с кешем. В консоли сетевого браузера вы должны увидеть ответ типа 304 Не изменено.
Конечно, вы можете добавить элемент в URL, чтобы обойти кеш:
updates.open('GET','scripts/check_for_notifications.php&nocache=' + new Date().getTime(), true);
Если это работает, вам нужно будет настроить сервер (apache или nginx), чтобы предотвратить кэшируется. Это чище, чем решение с отметкой времени. браузер не хранит кэшированные файлы без необходимости.
Apache .htaccess или Apache conf, что-то вроде
Header set Cache-Control "no-cache, no-store, must-revalidate"
Header set Pragma "no-cache"
Header set Expires 0
Nginx conf, что-то вроде
location = /check.php {
add_header 'Cache-Control' 'no-cache, no-store, must-revalidate';
expires off;
}
Вы также можете увидеть api: https: // hacks.mozilla.org/2016/03/referrer-and-cache-control-apis-for-fetch/
Будьте осторожны с вашим кодом, он может запустить несколько запросов одновременно и найти Если у вас слишком много пользователей, вы можете использовать DOS.
Если запросы занимают более 2 секунд из-за медленной работы сервера, другие запросы тем временем будут отправлены, что еще больше замедлит работу сервера ...
Да, у Вас нет немного довольно опций. Время записано с этой строкой в _write_gzip_header:
write32u(self.fileobj, long(time.time()))
Так как они не дают Вам способ переопределить время, можно сделать одну из этих вещей:
_write_gzip_header
функционируйте в свой производный класс, но с другим значением в этой строке.Вот пример (непротестированной) опции № 2:
class FakeTime:
def time(self):
return 1225856967.109
import gzip
gzip.time = FakeTime()
# Now call gzip, it will think time doesn't change!
Опция № 5 может быть самой чистой с точки зрения не в зависимости от внутренностей gzip (непротестированного) модуля:
class GzipTimeFixingFile:
def __init__(self, realfile):
self.realfile = realfile
self.pos = 0
def write(self, bytes):
if self.pos == 4 and len(bytes) == 4:
self.realfile.write("XYZY") # Fake time goes here.
else:
self.realfile.write(bytes)
self.pos += len(bytes)
Отправьте патч, в котором факторизуется вычисление метки времени. Это было бы почти наверняка принято.
В lib/gzip.py мы находим метод, который создает заголовок, включая часть, которая действительно содержит метку времени. В Python 2.5 это начинается на строке 143:
def _write_gzip_header(self):
self.fileobj.write('\037\213') # magic header
self.fileobj.write('\010') # compression method
fname = self.filename[:-3]
flags = 0
if fname:
flags = FNAME
self.fileobj.write(chr(flags))
write32u(self.fileobj, long(time.time())) # The current time!
self.fileobj.write('\002')
self.fileobj.write('\377')
if fname:
self.fileobj.write(fname + '\000')
Как Вы видите, это использует time.time () для выборки текущего времени. Согласно документам модуля онлайн, time.time "возвратит время как число с плавающей точкой, выраженное в секундах с эпохи в UTC". Так, при изменении этого на константу с плавающей точкой выбора можно было всегда выписывать те же заголовки. Я не вижу лучший способ сделать это, если Вы не хотите взломать библиотеку еще немного для принятия дополнительного параметрического усилителя времени, который Вы используете при установке по умолчанию для time.time (), когда это не указано, в этом случае, я уверен, что они любили бы его, если Вы отправили патч!
Это не симпатично, но Вы могли monkeypatch time.time временно с чем-то вроде этого:
import time
def fake_time():
return 100000000.0
def do_gzip(content):
orig_time = time.time
time.time = fake_time
# result = do gzip stuff here
time.time = orig_time
return result
Это не симпатично, но это, вероятно, работало бы.
Я послушал совет г-на Coventry и отправил патч. Однако, учитывая текущее состояние плана выпуска Python, с 3,0 просто за углом, я не ожидаю, что это обнаружится в выпуске в ближайшее время. Однако, мы будем видеть то, что происходит!
Тем временем мне нравится опция 5 г-на Batchelder передачи по каналу gzip потока через маленький пользовательский фильтр, который устанавливает поле метки времени правильно. Это походит на самый чистый подход. Как он демонстрирует, требуемый код является на самом деле довольно маленьким, хотя его пример действительно зависит для части его простоты на (в настоящее время допустимом) предположении что gzip
реализация модуля примет решение записать метку времени, использующую точно один четырехбайтовый вызов для write()
. Однако, я не думаю, что было бы очень трудно придумать полностью общую версию в случае необходимости.
Исправляющий обезьяну подход (иначе опция 2) довольно заманчив для ее простоты, но дает мне паузу, потому что я пишу библиотеку, которая звонит gzip
, не только автономная программа, и мне кажется, что кто-то мог бы попытаться звонить gzip
от другого потока, прежде чем мой модуль готов обратить свое изменение к gzip
глобальное состояние модуля. Это было бы особенно неудачно, если бы другой поток пытался вытянуть подобный исправляющий обезьяну трюк! Я признаю, что эта потенциальная проблема не звучит вероятной подойти на практике, но вообразить, как болезненный это должно было бы диагностировать такую путаницу!
Я могу неопределенно предположить пытаться сделать что-то хитрое и сложное и возможно не настолько соответствующий требованиям завтрашнего дня, чтобы так или иначе импортировать частную копию gzip
модуль и патч обезьяны, что, но той точкой фильтр кажется более простым и более прямым.