我有一个REST端点,在GET调用时返回一个列表,还有一个POST端点用于添加新项目和一个DELETE端点用于删除它们。这在Firefox和Chrome中起作用,在IE11中POST和DELETE也能够使用。然而,在IE11中,仅在页面初始加载时GET才能正常工作。刷新会返回缓存数据。我看过关于在Angular 1中出现此行为的帖子,但对于Angular 2(发布候选版1)没有找到相关内容。
我有一个REST端点,在GET调用时返回一个列表,还有一个POST端点用于添加新项目和一个DELETE端点用于删除它们。这在Firefox和Chrome中起作用,在IE11中POST和DELETE也能够使用。然而,在IE11中,仅在页面初始加载时GET才能正常工作。刷新会返回缓存数据。我看过关于在Angular 1中出现此行为的帖子,但对于Angular 2(发布候选版1)没有找到相关内容。
对于Angular 2及以上版本,覆盖RequestOptions
是添加 no-cache headers 最简单的方法:
import { Injectable } from '@angular/core';
import { BaseRequestOptions, Headers } from '@angular/http';
@Injectable()
export class CustomRequestOptions extends BaseRequestOptions {
headers = new Headers({
'Cache-Control': 'no-cache',
'Pragma': 'no-cache',
'Expires': 'Sat, 01 Jan 2000 00:00:00 GMT'
});
}
模块:
@NgModule({
...
providers: [
...
{ provide: RequestOptions, useClass: CustomRequestOptions }
]
})
今天我也遇到了这个问题(该死的IE)。
在我的项目中,我使用httpclient
,但它没有BaseRequestOptions
。
我们应该使用Http_Interceptor
来解决这个问题!
import { HttpHandler,
HttpProgressEvent,
HttpInterceptor,
HttpSentEvent,
HttpHeaderResponse,
HttpUserEvent,
HttpRequest,
HttpResponse } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
export class CustomHttpInterceptorService implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler):
Observable<HttpSentEvent | HttpHeaderResponse | HttpProgressEvent | HttpResponse<any> | HttpUserEvent<any>> {
const nextReq = req.clone({
headers: req.headers.set('Cache-Control', 'no-cache')
.set('Pragma', 'no-cache')
.set('Expires', 'Sat, 01 Jan 2000 00:00:00 GMT')
.set('If-Modified-Since', '0')
});
return next.handle(nextReq);
}
}
模块提供
@NgModule({
...
providers: [
...
{ provide: HTTP_INTERCEPTORS, useClass: CustomHttpInterceptorService, multi: true }
]
})
编辑:请查看下面的评论 - 在绝大多数情况下,这并不是必要的。
扩展Jimmy Ho上面的答案,我只想防止我的API调用被缓存,而不是其他受益于被缓存的静态内容。 我所有的API调用都是到包含“/api/”的URL,因此我修改了Jimmy Ho的代码,并添加了一个检查,仅在请求的URL包含“/api/”时才添加缓存标头:
import { HttpHandler,
HttpProgressEvent,
HttpInterceptor,
HttpSentEvent,
HttpHeaderResponse,
HttpUserEvent,
HttpRequest,
HttpResponse } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
export class CustomHttpInterceptorService implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler):
Observable<HttpSentEvent | HttpHeaderResponse | HttpProgressEvent | HttpResponse<any> | HttpUserEvent<any>> {
// Only turn off caching for API calls to the server.
if (req.url.indexOf('/api/') >= 0) {
const nextReq = req.clone({
headers: req.headers.set('Cache-Control', 'no-cache')
.set('Pragma', 'no-cache')
.set('Expires', 'Sat, 01 Jan 2000 00:00:00 GMT')
.set('If-Modified-Since', '0')
});
return next.handle(nextReq);
} else {
// Pass the request through unchanged.
return next.handle(req);
}
}
}
// cache-interceptor.service.ts
import { Injectable } from '@angular/core';
import {
HttpInterceptor,
HttpRequest,
HttpHandler,
} from '@angular/common/http';
@Injectable()
export class CacheInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler) {
const httpRequest = req.clone({
headers: req.headers
.set('Cache-Control', 'no-cache')
.set('Pragma', 'no-cache')
.set('Expires', 'Sat, 01 Jan 2000 00:00:00 GMT')
})
return next.handle(httpRequest)
}
}
// app.module.ts
import { HTTP_INTERCEPTORS } from '@angular/common/http'
import { CacheInterceptor } from './cache-interceptor.service';
// on providers
providers: [{ provide: HTTP_INTERCEPTORS, useClass: CacheInterceptor, multi: true }]
<meta http-equiv="cache-control" content="no-cache, must-revalidate, post-check=0, pre-check=0">
<meta http-equiv="expires" content="0">
<meta http-equiv="pragma" content="no-cache">
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Http, Response, XHRBackend, RequestOptions, RequestOptionsArgs,
URLSearchParams } from '@angular/http';
@Injectable()
export class NoCacheHttp extends Http {
constructor(backend: XHRBackend, options: RequestOptions) {
super(backend, options);
}
get(url: string, options?: RequestOptionsArgs): Observable<Response> {
//make options object if none.
if (!options) {
options = { params: new URLSearchParams() };
}
//for each possible params type, append a random number to query to force no browser caching.
//if string
if (typeof options.params === 'string') {
let params = new URLSearchParams(options.params);
params.set("k", new Date().getTime().toString());
options.params = params;
//if URLSearchParams
} else if (options.params instanceof URLSearchParams) {
let params = <URLSearchParams>options.params;
params.set("k", new Date().getTime().toString());
//if plain object.
} else {
let params = options.params;
params["k"] = new Date().getTime().toString();
}
return super.get(url, options);
}
}
Cache-Control: not-store, no-cache
但需要加上Pragma: no-cache
和Expires: 0
。 - cmaynard