Internet Explorer отображает данные кеша через Ajax Pull с результатом 304 - PullRequest
5 голосов
/ 13 января 2012

У меня есть инструмент, который прекрасно работает в Chrome и FF. Но в любых версиях IE браузер отображает информацию о кеше при выполнении Ajax-вытягивания для извлечения данных.

Вот мои настройки:

У меня есть критерии, которые я перебираю:

@foreach (var item in Model)
{
        <div class="sizeTDCriteria">
            @Html.DisplayFor(modelItem => item.Text)
        </div>
        <div class="sizeTDCriteriaAction">
            @Ajax.ImageActionLink(Url.Content("~/Content/images/icons/edit.png"), "Edit Criteria", "AddOrEditCriteria", "Management", new { competencySectionId = ViewBag.competencySectionId, criteriaId = item.Id }, new AjaxOptions { UpdateTargetId = "AddOrEditCriteriaFormContainer" }, new { @class = "iconPosition" })
            @Ajax.ImageActionLink(Url.Content("~/Content/images/icons/delete.png"), "Delete Criteria", "RemoveCriteria", "Management", new { criteriaId = item.Id }, new AjaxOptions { UpdateTargetId = "CompetenciesManagementWrapper" }, new { @class = "iconPosition" })
        </div>
}

ImageActionLink - это просто помощник, который создает ActionLink с изображением внутри, я попытался сделать это с обычным ActionLink, и проблема также возникает, поэтому вы можете игнорировать это. Я также пытался изменить весь ImageActionLink простым <img> с помощью триггера jQuery без разницы.

Что происходит, когда пользователь нажимает на ссылку «Изменить», он выполняет ajax-вызов «AddOrEditCriteria», который ActionResult находит критерии и отображает форму PartialView обратно в div «#AddOrEditCriteriaFormContainer». Пока все хорошо, это прекрасно работает во всех браузерах.

Но когда я нажимаю второй раз на это редактирование, вместо того, чтобы делать вызов ajax, IE просто отображает PartialView из того, что он имел в кэше, когда все другие браузеры правильно извлекают данные снова (что необходимо, так как view позволяет редактировать критерии, они могли быть отредактированы кем-то другим в это время).

Странная часть заключается в том, что IE выполняет вызов, но каким-то образом он никогда не достигает сервера, он просто использует кэш с помощью результата 304. Вы можете видеть из этого захвата сети:

URL Method  Result  Type    Received    Taken   Initiator   Wait??  Start?? Request??   Response??  Cache read??    Gap??
/PerformanceMVC/Management/AddOrEditCriteria?competencySectionId=178&criteriaId=369&X-Requested-With=XMLHttpRequest GET 304 text/html   182 B   < 1 ms  JS Library XMLHttpRequest
/PerformanceMVC/Management/AddOrEditCriteria?competencySectionId=178&criteriaId=369&X-Requested-With=XMLHttpRequest GET 304 text/html   182 B   < 1 ms  JS Library XMLHttpRequest
/PerformanceMVC/Management/AddOrEditCriteria?competencySectionId=178&criteriaId=369&X-Requested-With=XMLHttpRequest GET 200 text/html   1.53 KB 1.24 s  JS Library XMLHttpRequest

Последнее происходит первым, первые два были сделаны позже и получают возврат 304.

Я нашел способ исправить это, добавив параметр «breakcache» к вызову ajax со случайным числом, но это не похоже на хорошее решение.

Эта проблема запутала наших пользователей, потому что они видят данные, которые должны обновляться не все из-за IE.

1 Ответ

11 голосов
/ 13 января 2012

IE будет кешировать AJAX GET s, если вы не скажете этого.

Вы говорите это не через заголовок Cache-Control .

Итак, вот что мы делаем:

[CacheControl(HttpCacheability.NoCache), HttpGet]
public ActionResult MyAction() { return Json("Hi!", JsonRequestBehavior.AllowGet); }

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
public sealed class CacheControlAttribute : ActionFilterAttribute
{
    public CacheControlAttribute(HttpCacheability cacheability)
    {
        this._cacheability = cacheability;
    }

    public HttpCacheability Cacheability { get { return this._cacheability; } } 

    private HttpCacheability _cacheability;

    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        HttpCachePolicyBase cache = filterContext.HttpContext.Response.Cache;
        cache.SetCacheability(_cacheability);
    }
}
...