VBScript: отключить кеширование ответа сервера на HTTP-запрос GET URL.

Я хочу отключить кеш, используемый, когда вызов URL-адреса на сервер выполняется из VBScript, работающего в приложении на компьютере с Windows. Какую функцию/метод/объект я использую для этого?

Когда вызов выполняется в первый раз, мой сервер Apache на базе Linux возвращает ответ от запущенного сценария CGI Perl. Однако последующие запуски скрипта, похоже, используют тот же ответ, что и в первый раз, поэтому данные где-то кэшируются. Журналы моего сервера подтверждают, что сервер не вызывается в последующие разы, а только в первый раз.

Это то, что я делаю. Я использую следующий код из коммерческого приложения (не хочу упоминать это приложение, вероятно, не относящееся к моей проблеме):


With CreateObject("MSXML2.XMLHTTP")
  .open "GET", "http://myserver/cgi-bin/nsr/nsr.cgi?aparam=1", False
  .send
  nsrresponse =.responseText
End With

Есть ли функция/метод для вышеуказанного объекта для отключения кэширования, или я должен вызывать метод/функцию для отключения кэширования объекта ответа перед созданием URL-адреса?

Я искал здесь решение: http://msdn.microsoft.com/en-us/library/ms535874(VS.85).aspx - недостаточно полезно. А здесь: http://www.w3.org/TR/XMLHttpRequest/ - очень недружелюбно и тяжело читать.

Я также пытаюсь заставить не использовать кеш, используя настройки заголовка http и метаданные заголовка html-документа:

Фрагмент серверного сценария Perl CGI, который возвращает ответ вызывающему клиенту, устанавливает срок действия равным 0.


    print $httpGetCGIRequest->header(
        -type    => 'text/html',
        -expires => '+0s',
        );

Настройки заголовка Http в ответ отправлены обратно клиенту:


<html><head><meta http-equiv="CACHE-CONTROL" content="NO-CACHE"></head>
<body>
response message generated from server
</body>
</html>

Приведенные выше настройки заголовка http и html-документа не сработали, отсюда и мой вопрос.


person therobyouknow    schedule 16.06.2010    source источник


Ответы (3)


Я не думаю, что объект XMLHTTP сам реализует кэширование.

Вы отправляете новый запрос, как только вызываете на нем .send(). Весь смысл кэширования заключается в том, чтобы избежать отправки запросов, но здесь этого не происходит (насколько это касается вашего примера кода).

Но если объект используется в каком-либо браузере, тогда браузер может реализовать кэширование. В этом случае распространенный подход заключается в том, чтобы включить в оператор блокировку кеша: случайный параметр URL-адреса, который вы меняете каждый раз, когда делаете новый запрос (например, добавляете текущее время к URL-адресу).

В качестве альтернативы вы можете заставить свой сервер отправлять HTTP-заголовок Cache-Control: no-cache, no-store и посмотреть, поможет ли это.

<meta http-equiv="CACHE-CONTROL" content="NO-CACHE>, вероятно, бесполезен, и вы можете полностью отказаться от него.

person Tomalak    schedule 16.06.2010
comment
Большое спасибо за ваше время, Томалак. Я обнаружил, что COM-объект WinHttpRequest.5.1 не кэшируется. Однако мне придется провести более широкое тестирование, чтобы обрести уверенность. +1 за совет по разным URL-адресам каждый раз - это, безусловно, совет, который следует учитывать - я могу использовать его, а также WinHttpRequest.5.1 и расширить наш сервер, чтобы он справился с этим дополнительным параметром URL. Я, вероятно, включу поле времени запроса с высокой точностью, например. миллисекунд наверное. Это определенно стоит рассмотреть как часть решения. - person therobyouknow; 17.06.2010
comment
теперь принятый ответ, поскольку ваше случайное предложение URL-адреса попадает в причину маршрута - кэширование и ломает его, так что код вынужден каждый раз связываться с сервером. - person therobyouknow; 17.06.2010
comment
Чтобы создать уникальный идентификационный номер сеанса, я использую встроенные в VB функции Date и Timer, случайное число, а также имя компьютера/имя хоста ПК, где дата сценария дает сегодняшнюю дату, а Timer дает прошедшее время в миллисекундах. . Наряду со случайным числом и идентификатором машины это должно сделать вызов URL-адреса HTTP GET уникальным. Вероятность того, что 2 одинаковых вызова URL будут одинаковыми, равна нулю. - person therobyouknow; 17.06.2010
comment
' создать уникальный идентификатор сеанса, чтобы предотвратить использование кэшированных ответов от предыдущих URL-адресов sessionid = sessionid = Date & & Timer & & Rnd - person therobyouknow; 17.06.2010
comment
Установите objNetwork = CreateObject(WScript.Network) machineid = id_ & objNetwork.ComputerName - person therobyouknow; 17.06.2010
comment
@Rob: Вы также пробовали HTTP-заголовок Cache-Control: no-cache? Это также должно предотвратить кэширование. (Но взломщик кеша определенно сработает, независимо от обстоятельств.) - person Tomalak; 17.06.2010
comment
6 лет спустя, и ваш вопрос (@therobyouknow) и ответ (@Tomalak) спасут меня. Я реализовал предложение по прерыванию кеша и работает очень хорошо! Я использую MSXML2.XMLHTTP в старом программном обеспечении Fox Pro, он без проблем запрашивал PHP-сервер на общем хостинге, недавно я перешел на Google App Engine с Python 2.7 (с использованием инфраструктуры Flask), и эта проблема с кешем началась. Я предполагаю, что GAE имеет настройки по умолчанию для производительности, и кеш является одним из них. - person Manuel Lopera; 15.07.2016
comment
@Manuel Спасибо за отзыв! :) - person Tomalak; 15.07.2016
comment
+1 Мануэль, так приятно, что эта информация тебе помогла. +1 за благодарность Томалаку за его существенный вклад, который помог вам. - person therobyouknow; 16.07.2016

Вы можете использовать WinHTTP, который не кешировать HTTP-ответы. Вам все равно следует добавить директиву управления кешем (Cache-control: no-cache), используя SetRequestHeader, поскольку он предписывает промежуточным прокси и серверам не возвращать ранее кэшированный ответ.

person Garett    schedule 16.06.2010
comment
Итак, объект XMLHTTP выполняет кэширование запросов? - person Tomalak; 16.06.2010
comment
На самом деле, нет, не должно, что подтверждает вашу первоначальную точку зрения. - person Garett; 16.06.2010
comment
+1 и ответил. Я искал WinHttp и использовал WinHttp.WinHttpRequest.5.1. после небольшого дополнительного исследования. Ваше предложение послужило основой для этого, спасибо вам. Это успешно в том, что кэширование не происходит. Что мне нужно сделать сейчас, так это расширить мое тестирование (например, на разных машинах/конфигурациях) этого скрипта, чтобы повысить уверенность. Есть ли причина, по которой конфигурация кэширования этого объекта по умолчанию будет различаться на разных машинах? - person therobyouknow; 17.06.2010
comment
Я использовал его в приложении, которое было развернуто в нескольких версиях Windows без изменений. Итак, по моему опыту, его поведение было последовательным. В качестве примечания я теперь вспоминаю, что для этого приложения я также рассматривал ServerXMLHTTP, основанный на WinHTTP. В отличие от XMLHTTP, который основан на WININET и может объяснить, почему вы столкнулись с кэшированием. Дополнительные сведения см. в следующем документе: msdn.microsoft.com/ en-us/library/ms762278(VS.85).aspx - person Garett; 17.06.2010
comment
Этот ответ на использование WinHttp... решил мои проблемы с кэшированием на моей машине, и я буду его использовать. Но я все еще не уверен, могу ли я гарантировать такое же поведение без кэширования на всех машинах. Я переместил принятый ответ в Tomalak, поскольку они упоминают параметр случайного URL как взлом кеша. Это прямо ударяет и решает мою проблему по причине маршрута. Теперь я попробовал это, и кэширование избегается (при необходимости), если я использую MSXML2.XMLHTTP или WinHttpRequest.5.1. Извините за изменение принятого ответа - в качестве компенсации я добавил +1 к обоим вашим комментариям здесь - они полезны. - person therobyouknow; 17.06.2010
comment
Нет проблем, рад, что вы смогли найти решение. - person Garett; 17.06.2010

Если у вас есть контроль над приложением, на которое направлен запрос XMLHTTP (что верно в вашем случае), вы можете разрешить ему отправлять заголовки без кеша в ответе. Это решило проблему в моем случае.

Response.AppendHeader("pragma", "no-cache");
Response.AppendHeader("Cache-Control", "no-cache, no-store");

В качестве альтернативы вы также можете добавить строку запроса, содержащую случайное число, к каждому запрошенному URL-адресу.

person krizzzn    schedule 19.10.2011