253

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

4

17 回答 17

438

我没有为每个 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';
}]);
于 2013-11-04T15:48:18.547 回答
69

您可以在请求中附加一个唯一的查询字符串(我相信这是 jQuery 对 cache: false 选项所做的)。

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

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

于 2013-04-19T06:54:18.807 回答
28

你可以添加一个拦截器。

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 行。

于 2014-01-23T21:00:46.443 回答
14

我只是在 Angular 项目的 index.html 中添加了三个元标记,缓存问题在 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">
于 2014-06-06T20:12:13.597 回答
14

在另一个线程中复制我的答案

对于Angular 2 和更新版本no-cache,通过覆盖添加标题的最简单方法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 }
    ]
})
于 2017-06-15T07:20:41.713 回答
9

我工作的保证是这样的:

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

为了保证所有方法的正确使用,我必须合并上述解决方案中的 2 个,但您可以commonget或其他方法替换,即put, postdelete以使其适用于不同的情况。

于 2014-11-21T11:55:03.577 回答
8

这条唯一的线帮助了我(Angular 1.4.8):

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

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

于 2015-12-03T10:42:46.333 回答
7

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

myURL = myURL +"?random="+new Date().getTime();
于 2016-04-22T05:37:41.617 回答
6

我解决了将日期时间附加为随机数的问题:

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

上面的解决方案将起作用(通过在查询字符串中添加一个新参数来使 url 唯一)但我更喜欢提出的解决方案 [here]:Better Way to Prevent IE Cache in AngularJS? ,它在服务器级别处理此问题,因为它不是特定于 IE 的。我的意思是,如果不应该缓存该资源,请在服务器上执行(这与所使用的浏览器无关;它与资源有关)。

例如,在带有 JAX-RS 的 java 中,以编程方式为 JAX-RS v1 或 以声明方式为 JAX-RS v2。

我相信任何人都会想出如何去做

于 2014-06-06T13:09:20.010 回答
1

正确的服务器端解决方案:在 AngularJS 中防止 IE 缓存的更好方法?

[OutputCache(NoStore = true, Duration = 0, VaryByParam = "None")]
public ActionResult Get()
{
    // return your response
}
于 2015-01-17T16:08:05.383 回答
1

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

...
从“@angular/core”导入{可注射};
从“@angular/common/http”导入 { HttpClient、HttpHeaders、HttpParams };
...
 @Injectable()
导出类 MyService {

    私有标头:HttpHeaders;


    构造函数(私有http:HttpClient ..)
    {


        this.headers = 新的 HttpHeaders()
                    .append("内容类型", "应用程序/json")
                    .append("接受", "应用程序/json")
                    .append("LanguageCulture", this.headersLanguage)
                    .append("缓存控制", "无缓存")
                    .append("Pragma", "no-cache")                   
    }
}
……
于 2018-02-01T10:30:14.743 回答
1

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

于 2017-01-16T17:39:29.153 回答
0

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

  1. 将以下内容附加到您的 http 服务请求 url

//之前(下发一个)

this.httpService.get(this.serviceUrl + "/eAMobileService.svc/ValidateEngagmentName/" +engagementName , {})

//之后(工作正常)

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

  1. 禁用整个模块的缓存:-

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

于 2016-10-27T13:51:31.903 回答
0
meta http-equiv="Cache-Control" content="no-cache"

我刚刚将它添加到 View 并开始在 IE 上运行。确认可以在 Angular 2 上工作。

于 2017-01-18T03:47:56.857 回答
0

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

    let c=new Date().getTime();
    $http.get('url?d='+c)
于 2017-09-27T08:33:39.573 回答
-2

试试这个,它在类似的情况下对我有用:-

$http.get("your api url", {
headers: {
    'If-Modified-Since': '0',
    "Pragma": "no-cache",
    "Expires": -1,
    "Cache-Control": "no-cache, no-store, must-revalidate"
 }
})
于 2018-05-14T11:32:32.877 回答