在Angular 2中阻止IE11缓存GET调用

时间:2016-06-10 19:23:57

标签: javascript angular typescript internet-explorer-11 http-caching

我有一个休息端点,它在GET调用上返回一个列表。我还有一个POST端点来添加新项目,还有一个DELETE来删除它们。这适用于Firefox和Chrome,POST和DELETE适用于IE11。但是,IE11中的GET仅适用于页面的初始加载。刷新返回缓存的数据。我在Angular 1中看过关于这种行为的帖子,但Angular 2(发布候选人1)没有。

7 个答案:

答案 0 :(得分:54)

对于 Angular 2及更新,通过覆盖RequestOptions添加无缓存标头的最简单方法:

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 }
    ]
})

答案 1 :(得分:35)

今天,我也有这个问题,(该死的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 }
    ]
})

答案 2 :(得分:6)

转发stackoverflow响应Angular IE Caching issue for $http,你应该为每个'GET'请求添加标题'Pragma','no-cache','If-Modified-Since'。

角度2不再支持拦截器的场景。所以你应该按照What is httpinterceptor equivalent in angular2?中描述的那样扩展http。

Angular 4.3现在包含支持拦截器的HttpClient服务。

答案 3 :(得分:3)

编辑:请参见下面的评论-这是不必要的(在大多数情况下)。

在上述Jimmy Ho的回答的基础上,我只想防止对我的API调用进行缓存,而不是其他将从缓存中受益的静态内容。我所有的API调用都是针对包含“ / api /”的URL,所以我对Jimmy Ho的代码进行了修改,使其检查仅在请求的URL包含“ / api /”的情况下才添加缓存头:

error: serializer for text/html; charset=utf-8 doesn't exist

}

答案 4 :(得分:0)

有点晚了,但我遇到了同样的问题。对于 Angular 4.X ,我写了一个自定义Http类,在末尾附加一个随机数,以防止IE缓存。它基于dimeros的第二个链接(What is httpinterceptor equivalent in angular2?)。 警告:不保证100%无错误。

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

答案 5 :(得分:0)

禁用带有元HTML标签的浏览器缓存:-

<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">

答案 6 :(得分:0)

如上所述,您可以使用http请求拦截器修改或设置请求的新标头。 以下是在HTTP请求拦截器上为以后的Angular版本( Angular 4 + )设置标头的简单得多的方法。这种方法只会设置或更新某个请求标头。这是为了避免删除或覆盖一些重要的标头,例如授权标头。

// 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 }]