現在、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
});
}
Binarygiantが要求したように、回答としてコメントを投稿しています。サーバー側の応答にNo-Cacheヘッダーを追加することで、この問題を解決しました。これはGETリクエストに対してのみ行う必要があることに注意してください。他のリクエストは正常に機能するようです。
binarygiantは、これを行う方法をnode/expressに投稿しました。 ASP.NET MVCで次のように実行できます。
[OutputCache(NoStore = true, Duration = 0, VaryByParam = "None")]
public ActionResult Get()
{
// return your response
}
私の他の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';
}]);
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 }
);
}
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();
});
インターセプターを追加して一意のリクエスト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;
}
};
});
私はそれを解決します:
$http.get("/your_url?rnd="+new Date().getTime()).success(function(data, status, headers, config) {
console.log('your get response is new!!!');
});
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;
}
このアプローチでは:
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でもありません。
申し訳ありませんが、安全であり、過去の実際の日付を使用してください。
サーバー出力を制御できる場合は、代わりにキャッシュヘッダーを追加しないことをお勧めします。
私の解決策は、サーバーに_Cache-Control: no-cache
_ヘッダーを追加し、さらに状態を変更する前に$templateCache.remove()
を追加することでした。 Angular-ui/ui-routerを使用しています。 IE11とEdgeブラウザに問題がありました。
_$templateCache.remove('/partials/details.html');
$state.go('details');
_