更好的方法来防止AngularJS中的IE缓存?

bin*_*ant 60 caching angularjs

我目前使用service/$ resource来进行ajax调用(在这种情况下为GET),并且IE缓存调用以便无法从服务器检索新数据.我使用了一种技术,我通过谷歌搜索创建一个随机数并将其附加到请求,以便IE不会去缓存数据.

有没有比将cacheKill添加到每个请求更好的方法?

工厂代码

.factory('UserDeviceService', function ($resource) {

        return $resource('/users/:dest', {}, {
            query: {method: 'GET', params: {dest: "getDevicesByUserID"}, isArray: true }
        });
Run Code Online (Sandbox Code Playgroud)

来自控制器的呼叫

$scope.getUserDevices = function () {
        UserDeviceService.query({cacheKill: new Date().getTime()},function (data) {
            //logic
        });
    }
Run Code Online (Sandbox Code Playgroud)

cnm*_*muc 50

如我在其他帖子中所述,您可以在$ httpProvider中全局禁用缓存:

myModule.config(['$httpProvider', function($httpProvider) {
    //initialize get if not there
    if (!$httpProvider.defaults.headers.get) {
        $httpProvider.defaults.headers.get = {};    
    }    

    // Answer edited to include suggestions from comments
    // because previous version of code introduced browser-related errors

    //disable IE ajax request caching
    $httpProvider.defaults.headers.get['If-Modified-Since'] = 'Mon, 26 Jul 1997 05:00:00 GMT';
    // extra
    $httpProvider.defaults.headers.get['Cache-Control'] = 'no-cache';
    $httpProvider.defaults.headers.get['Pragma'] = 'no-cache';
}]);
Run Code Online (Sandbox Code Playgroud)


Ufu*_*arı 36

作为binarygiant请求我发布我的评论作为答案.我通过向服务器端的响应添加No-Cache标头解决了这个问题.请注意,您必须仅为GET请求执行此操作,其他请求似乎正常工作.

binarygiant发布了如何在node/express上执行此操作.您可以在ASP.NET MVC中执行此操作:

[OutputCache(NoStore = true, Duration = 0, VaryByParam = "None")]
public ActionResult Get()
{
    // return your response
}
Run Code Online (Sandbox Code Playgroud)

  • 这是干实施吗? (2认同)

bin*_*ant 33

在is实例中启用noCache是​​实现此目的的最佳方法:

在node/express中,这可以防止IE缓存这些请求:

app.use(function noCache(req, res, next) {
    res.header("Cache-Control", "no-cache, no-store, must-revalidate");
    res.header("Pragma", "no-cache");
    res.header("Expires", 0);
    next();
});
Run Code Online (Sandbox Code Playgroud)


Use*_*rol 33

对于那些使用ASP.NET Web API 2的人来说,等效的解决方案就是这样(Web API不使用与MVC相同的缓存逻辑):

public class NoCacheHeaderFilter : ActionFilterAttribute
{
    public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
    {
        if (actionExecutedContext.Response != null) // can be null when exception happens
        {
            actionExecutedContext.Response.Headers.CacheControl =
                new CacheControlHeaderValue { NoCache = true, NoStore = true, MustRevalidate = true };
            actionExecutedContext.Response.Headers.Pragma.Add(new NameValueHeaderValue("no-cache"));

            if (actionExecutedContext.Response.Content != null) // can be null (for example HTTP 400)
            {
                actionExecutedContext.Response.Content.Headers.Expires = DateTimeOffset.UtcNow;
            }
         }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后将其附加到WebApiConfig.cs中:

public static void Register(HttpConfiguration config)
{
    ....
    config.Filters.Add(new NoCacheHeaderFilter());

    config.Routes.MapHttpRoute(
        name: "DefaultApi",
        routeTemplate: "api/{controller}/{id}",
        defaults: new { id = RouteParameter.Optional }
    );
}
Run Code Online (Sandbox Code Playgroud)

  • 这解决了我们的问题.我们还必须在`OnActionExecuted`事件中添加`if(actionExecutedContext.Request.Method.Method =="GET")`以使其仅在GET请求中触发 (4认同)
  • 你必须与HttpMethod进行比较,而不仅仅是字符串.像这样:`actionExecutedContext.Request.Method == HttpMethod.Get` (3认同)

dil*_*aik 12

你可以添加一个拦截器来生成唯一的请求URL.您也可以删除console.log调用

myModule.config(['$httpProvider', function($httpProvider) {
 $httpProvider.interceptors.push('noCacheInterceptor');
}]).factory('noCacheInterceptor', function () {
            return {
                request: function (config) {
                    console.log(config.method);
                    console.log(config.url);
                    if(config.method=='GET'){
                        var separator = config.url.indexOf('?') === -1 ? '?' : '&';
                        config.url = config.url+separator+'noCache=' + new Date().getTime();
                    }
                    console.log(config.method);
                    console.log(config.url);
                    return config;
               }
           };
    });
Run Code Online (Sandbox Code Playgroud)