$ http에 대한 각도 IE 캐싱 문제


251

IE에서 보낸 모든 아약스 호출은 Angular에 의해 캐시되며 304 response모든 후속 호출에 대해 a 를 얻습니다 . 요청은 동일하지만 제 경우에는 응답이 동일하지 않습니다. 이 캐시를 비활성화하고 싶습니다. cache attribute$ http.get에 추가를 시도 했지만 여전히 도움이되지 않았습니다. 이 문제를 어떻게 해결할 수 있습니까?

답변:


439

각 단일 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';
}]);

78
If-Modified-Since헤더 차종은 + iisnode 던져 통해로드 모든 html 파일 400 잘못된 요청 IIS ngIncludengView. 다음 두 헤더가 나를 위해 문제를 해결했습니다 (캐싱 문제가없는 Chrome에서 가져 왔습니다) $httpProvider.defaults.headers.get['Cache-Control'] = 'no-cache'; $httpProvider.defaults.headers.get['Pragma'] = 'no-cache';
Langdon

4
내 의견으로는이 답변은 답변으로 표시되어야하며 Martin이 제공 한 솔루션은 작동하지만 실제 수정보다 해킹에 가깝습니다.
Robba

4
이것은 내 로컬 GET 요청에 효과적이지만 GET 메소드 대신 OPTIONS 메소드를 사용하여 시작하려는 CORS 요청이 발생했습니다. 타사 서버는 OPTIONS 메서드를 지원하지 않으므로 jQuery.get ()을 사용하여 해당 요청을 만들고 응답 핸들러에서 $ scope.apply ()를 사용하는 것입니다.
Ben

13
If-Modified-Since = "0"헤더를 사용하면 Tomcat이 중단됩니다 ( 0유효한 값 RFC 가 아니기 때문에 헤더 날짜 구문 분석 문제 ). Mon, 26 Jul 1997 05:00:00 GMT대신 값 을 사용하여 수정 했습니다.
lopisan

6
"If-Modified-Since"헤더를 사용하지 않았으며 그없이 작동했습니다. 다른 두 개만 필요합니다.
마이클 Mahony

69

요청에 고유 한 쿼리 문자열을 추가 할 수 있습니다 (jQuery가 cache : false 옵션으로 수행하는 작업이라고 생각합니다).

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

더 나은 솔루션은 서버에 액세스 할 수있는 경우 캐싱을 방지하기 위해 필요한 헤더가 설정되어 있는지 확인할 수 있습니다. ASP.NET MVC 이 답변을 사용 하면 도움 될 수 있습니다.


2
$http.get(url+ "?"+new Date().toString())매개 변수를 사용하지 않고 쿼리 문자열에 추가하는 또 다른 표현입니다.
Davut Gürbüz

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 줄을 제거해야합니다.


그리고 당신은 $log그들을 꺼내 잊어 경우에 사용해야합니다 .
Carl G

2
IE에서 심각한 캐싱 문제가 발생하여 중요한 부분이 실행되지 않아 빈 페이지가 나타납니다. propsed interceptor를 사용하여이 문제를 해결했습니다! +1
raoulinski

헤더를 추가하면 CORS 및 IE의 프리 플라이트 요청 트리거 동작 문제를 피할 수 있기 때문에 이것이 최선의 방법이라고 생각합니다. 이것은 추가적인 문제가 발생하지 않는 가장 안전한 방법 인 것 같습니다
chrismarx

@ dilip pattnaik :-왜이 문제가 각도 및 즉 발생합니까?
MiHawk

14

난 그냥 각도 프로젝트에서 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">

2
우리 index.html는 IE11이 AJAX 요청을 캐싱하고 있음을 알았을 때 이미 메타 태그를 가지고있었습니다 $httpProvider.
walen

14

다른 스레드에서 내 답변을 복제 합니다 .

들어 각도 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 }
    ]
})

브라우저 요청이 아닌 서버 응답의 헤더가 아닌가? (나는 If-Modified-Since위의 방법을 사용하여 과거 어느 날 날짜를 설정할 수 있다고 상상할 수있다 .)
Arjan

@Vitaliy :-왜이 문제가 각도 및 즉 발생합니까?
MiHawk

접근 방식은 이미 존재하는 사용자 정의 헤더를 제거합니다. 따라서 새 Header 객체를 만드는 대신 다음을 수행하십시오. headers: req.headers .set('Cache-Control', 'no-cache') .set('Pragma', 'no-cache') .set('Expires', 'Sat, 01 Jan 2000 00:00:00 GMT')
Chamika Goonetilaka

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 병합했다,하지만 당신은 대체 할 수 common와 함께 get또는 다른 방법 즉 put, post, delete다른 경우에이 작업을 할 수 있습니다.


코드에서 이것을 angular.js 파일에 추가 한 위치를 알려주시겠습니까? 어떤 줄 #?
JonathanScialpi

@JonathanScialpi 나는 그것을 어디에 넣을 수 있는지 보여주기 위해 그것을 업데이트했다. 익명 함수 내에있는 것은 중요하지 않습니다.
marksyzm

@marksyzm u plzz는이 줄의 의미를 말해 줄 수 있습니다if (!$httpProvider.defaults.headers.get) { $httpProvider.defaults.headers.common = {}; }
Monojit Sarkar

@MonojitSarkar Ah, if 구문에서
headers.common이어야했는데

1
["If-Modified-Since"] = "0"불법이며 일부 백엔드에서 잘못된 요청을 생성합니다. 날짜 여야합니다.
jenson-button-event 이벤트

8

이 줄만 도움이되었습니다 (Angular 1.4.8).

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

UPD : 문제는 IE11이 적극적인 캐싱을 수행한다는 것입니다. Fiddler를 살펴볼 때 F12 모드에서 요청이 "Pragma = no-cache"를 전송하고 페이지를 방문 할 때마다 끝 점이 요청되는 것을 알았습니다. 그러나 일반 모드에서는 페이지를 처음 방문했을 때 끝 점이 한 번만 요청되었습니다.


1
참고로,이 답변은 Azure의 Blob 저장소에서 파일을 요청할 때 CORS 문제를 일으켜 추적하기가 어렵지만 결국 이것이 원인임을 알았습니다. pragma 헤더를 제거하면 CORS 문제가 해결되었지만 IE 캐싱 문제가 다시 해결되었습니다.
keithl8041

7

캐싱을 피하기 위해 한 가지 옵션은 동일한 리소스 또는 데이터에 다른 URL을 제공하는 것입니다. 다른 URL을 생성하기 위해 URL 끝에 임의의 쿼리 문자열을 추가 할 수 있습니다. 이 기술은 JQuery, Angular 또는 기타 유형의 아약스 요청에 적용됩니다.

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

6

날짜 시간을 임의의 숫자로 추가하여 해결했습니다.

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

:-왜이 문제가 각도와 즉 발생합니까?
MiHawk

4

위의 솔루션은 작동하지만 (쿼리 문자열에 새로운 매개 변수를 추가하여 URL을 고유하게 만드십시오) 해결책을 선호하는 솔루션은 여기입니다 : AngularJS에서 IE 캐시를 방지하는 더 나은 방법이는 IE에만 ​​국한되지 않으므로 서버 수준에서이를 처리합니다. 즉, 해당 리소스를 캐시하지 않으면 서버에서 수행하십시오 (사용 된 브라우저와 관련이 없으며 리소스에 흥미가 없습니다).

예를 들어 JAX-RS가있는 Java 에서는 JAX-RS v1에 대해 프로그래밍 방식 으로 또는 선언적으로 수행하십시오. JAX-RS v2의 경우 으로 수행하십시오.

나는 누군가가 그것을하는 방법을 알아낼 것이라고 확신한다.


1
정교하게 만들 수 있지만 이것이 올바른 방법입니다. 클라이언트 쪽은 캐시 할 항목을 선택해서는 안되지만 클라이언트에게 캐시해야 할 항목을 알려 주어야하는 서버 여야합니다.
Archimedes Trajano

나는 이것이 올바른 방법이어야한다는 것에 전적으로 동의합니다
smnbbrv

1

이것은 약간 오래된 것이지만 같은 솔루션은 더 이상 사용되지 않습니다. 서버가 캐시를 처리하거나 캐시하지 않도록하십시오 (응답 중). 캐싱을 보장하지 않는 유일한 방법 (프로덕션의 새 버전에 대한 생각)은 버전 번호로 js 또는 css 파일을 변경하는 것입니다. 나는 웹팩으로 이것을한다.


1

또한 servce에서 예를 들어 헤더를 설정하려고 시도 할 수 있습니다.

...
"@ angular / core"에서 import {Injectable};
"@ angular / common / http"에서 import {HttpClient, HttpHeaders, HttpParams};
...
 @ 인젝터 블 ()
수출 클래스 MyService {

    개인 헤더 : HttpHeaders;


    생성자 (private http : HttpClient ..) 
    {


        this.headers = 새로운 HttpHeaders ()
                    .append ( "Content-Type", "application / json")
                    .append ( "수락", "응용 프로그램 / json")
                    .append ( "LanguageCulture", this.headersLanguage)
                    .append ( "캐시 제어", "캐시 없음")
                    .append ( "프 래그 마", "노 캐시")                   
    }
}
....


0

이 문제는 IE 캐싱 문제로 인한 것으로 f12 키를 눌러 IE 디버그 모드에서 테스트 할 수 있습니다 (디버그 모드에서는 정상적으로 작동합니다) .IE는 페이지를 호출 할 때마다 서버 데이터를 가져 가지 않습니다. 캐시의 데이터 이를 비활성화하려면 다음 중 하나를 수행하십시오.

  1. http 서비스 요청 URL에 다음을 추가하십시오.

// 전에 (발행 된 1)

this.httpService.get (this.serviceUrl + "/eAMobileService.svc/ValidateEngagmentName/"+ 참여 이름, {})

// 후 (잘 작동)

this.httpService.get (this.serviceUrl + "/eAMobileService.svc/ValidateEngagmentName/"+ 참여 이름 + "? DateTime ="+ new Date (). getTime () + '', {캐시 : false})

  1. 전체 모듈에 대한 캐시를 비활성화하십시오 :-

$ httpProvider.defaults.headers.common [ 'Pragma'] = '노 캐시';


0
meta http-equiv="Cache-Control" content="no-cache"

방금 이것을 View에 추가하고 IE에서 작업하기 시작했습니다. Angular 2에서 작동하도록 확인되었습니다.


0

옵션은 각 요청마다 캐시를 ​​지우지 않아도 타임 스탬프를 추가하는 간단한 방법을 사용하는 것입니다.

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

-2

이것을 시도해보십시오, 그것은 비슷한 경우에 저에게 효과적이었습니다.

$http.get("your api url", {
headers: {
    'If-Modified-Since': '0',
    "Pragma": "no-cache",
    "Expires": -1,
    "Cache-Control": "no-cache, no-store, must-revalidate"
 }
})
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.