Javascript $http的角度IE缓存问题

Javascript $http的角度IE缓存问题,javascript,caching,angularjs,Javascript,Caching,Angularjs,从IE发送的所有ajax调用都由Angular缓存,对于所有后续调用,我都会得到304响应。虽然请求是相同的,但在我的情况下,响应是不同的。我想禁用这个缓存。我尝试将缓存属性添加到$http.get,但仍然没有帮助。如何解决这个问题?您可以在请求中附加一个唯一的querystring(我相信这就是jQuery使用cache:false选项所做的) $http({ url: '...', params: { 'foobar': new Date().getTime() } })

从IE发送的所有ajax调用都由Angular缓存,对于所有后续调用,我都会得到
304响应。虽然请求是相同的,但在我的情况下,响应是不同的。我想禁用这个缓存。我尝试将
缓存属性添加到$http.get,但仍然没有帮助。如何解决这个问题?

您可以在请求中附加一个唯一的querystring(我相信这就是jQuery使用cache:false选项所做的)

$http({
    url: '...',
    params: { 'foobar': new Date().getTime() }
})

也许更好的解决方案是,如果您有权访问服务器,那么您可以确保设置了必要的头以防止缓存。如果您使用的是
ASP.NET MVC
,可能会有所帮助。

我没有为每个GET请求禁用缓存,而是在$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';
}]);

您可以添加一个拦截器

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;
               }
           };
    });
您应该在验证后删除console.log行。

上述解决方案将起作用(通过在querystring中添加一个新参数使url唯一),但我更喜欢propose[此处]:,该解决方案在服务器级别处理此问题,因为它不特定于IE。我的意思是,如果不应缓存该资源,请在服务器上执行此操作(这与所使用的浏览器无关;它与资源无关)

例如,在使用JAX-RS的java中,为JAX-RSV1或JAX-RSV2执行此操作


我相信任何人都会想出办法的

我只是在angular project的index.html中添加了三个meta标记,IE解决了缓存问题

<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Cache-Control" content="no-cache">
<meta http-equiv="Expires" content="Sat, 01 Dec 2001 00:00:00 GMT">

我将datetime作为一个随机数附加在后面:

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

我工作过的保证书是这样的:

myModule.config(['$httpProvider', function($httpProvider) {
    if (!$httpProvider.defaults.headers.common) {
        $httpProvider.defaults.headers.common = {};
    }
    $httpProvider.defaults.headers.common["Cache-Control"] = "no-cache";
    $httpProvider.defaults.headers.common.Pragma = "no-cache";
    $httpProvider.defaults.headers.common["If-Modified-Since"] = "Mon, 26 Jul 1997 05:00:00 GMT";
}]);

为了保证所有方法的正确使用,我必须合并上述两种解决方案,但您可以使用
get
或其他方法(即
put
post
delete
)替换
common
,以使其适用于不同的情况。

正确的服务器端解决方案:

只有这一行对我有帮助(1.4.8):


UPD:问题在于IE11的缓存非常激进。当我查看Fiddler时,我注意到在F12模式下,请求发送“Pragma=no cache”每次我访问页面时都会请求端点。但在正常模式下,在我第一次访问页面时只请求一次端点。

为了避免缓存,一个选项是为同一资源或数据提供不同的URL。要生成不同的URL,可以在URL的末尾添加随机查询字符串。此技术适用于JQuery、Angular或其他类型的ajax请求

myURL = myURL +"?random="+new Date().getTime();

此问题是由于IE缓存问题造成的,正如您所说,您可以在IE调试模式下按f12进行测试(在调试模式下可以正常工作)。IE不会在每次页面调用时获取服务器数据,而是从缓存中获取数据。要禁用此功能,请执行以下操作之一:

  • 在http服务请求url中附加以下内容
  • //前(下发)

    this.httpService.get(this.serviceUrl+”/eAMobileService.svc/validateengagementname/“+engagementName,{})

    //之后(罚款)

    this.httpService.get(this.serviceUrl+”/eAMobileService.svc/validateengagementname/“+engagementName+”?DateTime=“+new Date().getTime()+”,{cache:false})

  • 禁用整个模块的缓存:-

  • $httpProvider.defaults.headers.common['Pragma']='no cache';

    这有点过时了,但是:像这样的解决方案已经过时了。让服务器处理缓存或不处理缓存(在响应中)。保证不缓存的唯一方法(考虑生产中的新版本)就是用一个版本号来更改js或css文件。我用webpack来做这个

    meta http-equiv="Cache-Control" content="no-cache"
    
    我刚刚把这个添加到视图中,它开始在IE上工作。确认可以在Angular 2上工作。

    复制

    对于Angular 2及更新版本,通过覆盖
    请求选项
    ,添加
    无缓存
    头的最简单方法是:

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

    一种选择是使用简单的方法,在每个请求中添加一个时间戳,而无需清除缓存

        let c=new Date().getTime();
        $http.get('url?d='+c)
    

    您还可以尝试在服务中设置标题,例如:

    ... import { Injectable } from "@angular/core"; import { HttpClient, HttpHeaders, HttpParams } from "@angular/common/http"; ... @Injectable() export class MyService { private headers: HttpHeaders; constructor(private http: HttpClient..) { this.headers = new HttpHeaders() .append("Content-Type", "application/json") .append("Accept", "application/json") .append("LanguageCulture", this.headersLanguage) .append("Cache-Control", "no-cache") .append("Pragma", "no-cache") } } .... ... 从“@angular/core”导入{Injectable}”; 从“@angular/common/http”导入{HttpClient,HttpHeaders,HttpParams}; ... @可注射() 导出类MyService{ 私有头:HttpHeaders; 构造函数(私有http:HttpClient..) { this.headers=新的HttpHeaders() .append(“内容类型”、“应用程序/json”) .append(“接受”、“应用程序/json”) .append(“LanguageCulture”,this.headersLanguage) .append(“缓存控制”、“无缓存”) .append(“Pragma”,“无缓存”) } } ....
    试试这个,在类似的情况下,它对我很有效:-

    $http.get("your api url", {
    headers: {
        'If-Modified-Since': '0',
        "Pragma": "no-cache",
        "Expires": -1,
        "Cache-Control": "no-cache, no-store, must-revalidate"
     }
    })
    

    If-Modified-Since
    头使得IIS+iisnode对通过
    ngInclude
    ngView
    加载的每个html文件抛出400个错误请求。以下两个头为我解决了这个问题(我从没有缓存问题的Chrome中提取它们):
    $httpProvider.defaults.headers.get['Cache-Control']='no cache';
    $httpProvider.defaults.headers.get['Pragma']='no cache';
    在我看来,这个答案应该被标记为答案,虽然Martin提供的解决方案确实有效,但它更像是一个黑客而不是一个实际的修复程序。这对我的本地GET请求有效,但它导致我发出的一个CORS请求开始使用OPTIONS方法而不是GET方法。第三方服务器不支持rt OPTIONS方法,因此我的解决方法是使用jQuery.get()发出该请求,并在响应处理程序中使用$scope.apply()。如果自=“0”
    头被修改,则使用
    头会破坏Tomcat(解析头日期的问题,因为
    0
    不是有效值)。修复 ... import { Injectable } from "@angular/core"; import { HttpClient, HttpHeaders, HttpParams } from "@angular/common/http"; ... @Injectable() export class MyService { private headers: HttpHeaders; constructor(private http: HttpClient..) { this.headers = new HttpHeaders() .append("Content-Type", "application/json") .append("Accept", "application/json") .append("LanguageCulture", this.headersLanguage) .append("Cache-Control", "no-cache") .append("Pragma", "no-cache") } } ....
    $http.get("your api url", {
    headers: {
        'If-Modified-Since': '0',
        "Pragma": "no-cache",
        "Expires": -1,
        "Cache-Control": "no-cache, no-store, must-revalidate"
     }
    })