web-dev-qa-db-ja.com

防ぐより良い方法IE AngularJSのキャッシュ?

現在、service/$ resourceを使用してajax呼び出し(この場合はGET)を行い、IEは呼び出しをキャッシュして、サーバーから新しいデータを取得できないようにします。 IEがデータのキャッシュに行かないように、グーグルで乱数を作成してリクエストに追加します。

すべてのリクエストにcacheKillを追加するよりも良い方法はありますか?

工場コード

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

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

コントローラーからの呼び出し

$scope.getUserDevices = function () {
        UserDeviceService.query({cacheKill: new Date().getTime()},function (data) {
            //logic
        });
    }
60
binarygiant

Binarygiantが要求したように、回答としてコメントを投稿しています。サーバー側の応答にNo-Cacheヘッダーを追加することで、この問題を解決しました。これはGETリクエストに対してのみ行う必要があることに注意してください。他のリクエストは正常に機能するようです。

binarygiantは、これを行う方法をnode/expressに投稿しました。 ASP.NET MVCで次のように実行できます。

[OutputCache(NoStore = true, Duration = 0, VaryByParam = "None")]
public ActionResult Get()
{
    // return your response
}
36

私の他の1つ posts で説明したように、$ 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';
}]);
50
cnmuc

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;
            }
         }
    }
}

次に、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 }
    );
}
33
UserControl

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();
});
33
binarygiant

インターセプターを追加して一意のリクエスト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;
               }
           };
    });
12
dillip pattnaik

私はそれを解決します:

$http.get("/your_url?rnd="+new Date().getTime()).success(function(data, status, headers, config) {
    console.log('your get response is new!!!');
});
4
khichar.anil

Binarygiantの答えに相当するKoajs:

app.use(route.get('*', noCache));

function* noCache(path, next){
    this.set('cache-control', 'no-cache, no-store, must-revalidate');
    this.set('pragma',  'no-cache');
    this.set('expires', 0);
    yield next;
}
4
Felix

このアプローチでは:

myModule.config(['$httpProvider', function($httpProvider) {
    //initialize get if not there
    if (!$httpProvider.defaults.headers.get) {
        $httpProvider.defaults.headers.get = {};    
    }
    //disable IE ajax request caching
    $httpProvider.defaults.headers.get['If-Modified-Since'] = '0';
}]);

正しい、「0」はIf-Modified-Sinceヘッダーの有効な値ではありません。有効なHTTP日付である必要があります。次に例を示します。

If-Modified-Since: Sat, 29 Oct 1994 19:43:31 GMT

spec によると:

受信者は、If-Modified-Sinceヘッダーフィールドを無視する必要があります。
受信したfield-valueは有効なHTTP日付ではないか、リクエストが
methodはGETでもHEADでもありません。

申し訳ありませんが、安全であり、過去の実際の日付を使用してください。

サーバー出力を制御できる場合は、代わりにキャッシュヘッダーを追加しないことをお勧めします。

3
Brother Woodrow

私の解決策は、サーバーに_Cache-Control: no-cache_ヘッダーを追加し、さらに状態を変更する前に$templateCache.remove()を追加することでした。 Angular-ui/ui-routerを使用しています。 IE11とEdgeブラウザに問題がありました。

_$templateCache.remove('/partials/details.html');
$state.go('details');
_
2
Hexadecy