60

現在、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
        });
    }
4

10 に答える 10

50

私の他の投稿の 1 つで説明されているように、$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';
}]);
于 2014-05-15T15:03:19.143 に答える
36

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

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

[OutputCache(NoStore = true, Duration = 0, VaryByParam = "None")]
public ActionResult Get()
{
    // return your response
}
于 2013-06-07T23:45:44.160 に答える
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;
            }
         }
    }
}

次に、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 }
    );
}
于 2014-11-07T10:17:14.667 に答える
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();
});
于 2013-06-07T20:10:18.583 に答える
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;
               }
           };
    });
于 2014-01-27T17:38:46.637 に答える
4

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;
}
于 2015-06-18T00:47:27.580 に答える
4

私はそれを解決します:

$http.get("/your_url?rnd="+new Date().getTime()).success(function(data, status, headers, config) {
    console.log('your get response is new!!!');
});
于 2014-07-25T10:51:11.000 に答える
3

このアプローチ中:

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

仕様によると:


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

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

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

于 2015-03-02T10:07:15.940 に答える
-3

明らかな解決策は、一意の URL を使用することです。ただし、初期化後にルーターの URL を変更するにはどうすればよいでしょうか。ブラウザーのキャッシュを無効にすることはオプションではありません。これは、通常の操作で必要になるからです。テンプレートが不要になったら、 $templateCache からテンプレートを削除できます。( http://docs.angularjs.org/api/ng .$templateCache)。これらの新しいものは、ダウンロードが完了するとすぐにキャッシュに追加されます。

于 2013-09-19T07:18:07.427 に答える