Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Better Way to Prevent IE Cache in AngularJS?

I currently use service/$resource to make ajax calls (GET in this case), and IE caches the calls so that fresh data cannot be retrieved from the server. I have used a technique I found by googling to create a random number and append it to the request, so that IE will not go to cache for the data.

Is there a better way than adding the cacheKill to every request?

factory code

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

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

Call from the controller

$scope.getUserDevices = function () {
        UserDeviceService.query({cacheKill: new Date().getTime()},function (data) {
            //logic
        });
    }
like image 357
binarygiant Avatar asked Jun 06 '13 20:06

binarygiant


People also ask

How do I stop Internet Explorer from caching?

Select the HTTP Headers tab. Select the Add button in the Custom HTTP Headers group, and add Cache-Control for the header name and no-cache for the header value.

How do you stop a flask from caching?

To disable caching in Python Flask, we can set the response headers to disable cache. to create the add_header function that adds a few headers to the response after each request is done. We make it run after each request with the @app. after_request decorator.

How does angular use cached data?

GET requests can be cached. They just get data from the server without changing them. If no POST , PUT , or DELETE request occurs before the next GET request, the data from the last GET request does not change. We simply return the previous data or response without hitting the server.


3 Answers

As described in one of my other posts, you could disable caching globally in the $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';
}]);
like image 195
cnmuc Avatar answered Oct 12 '22 07:10

cnmuc


As binarygiant requested I am posting my comment as an answer. I have solved this problem by adding No-Cache headers to the response on server side. Note that you have to do this for GET requests only, other requests seems to work fine.

binarygiant posted how you can do this on node/express. You can do it in ASP.NET MVC like this:

[OutputCache(NoStore = true, Duration = 0, VaryByParam = "None")]
public ActionResult Get()
{
    // return your response
}
like image 36
Ufuk Hacıoğulları Avatar answered Oct 12 '22 06:10

Ufuk Hacıoğulları


For those using ASP.NET Web API 2 the equivalent solution would be this (Web API does not use same caching logic as 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;
            }
         }
    }
}

then attach it in 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 }
    );
}
like image 33
UserControl Avatar answered Oct 12 '22 05:10

UserControl