AJAX 호출 결과의 브라우저 캐싱 방지


262

를 사용하여 동적 콘텐츠를로드 $.get()하면 결과가 브라우저에 캐시됩니다.

QueryString에 임의의 문자열을 추가하면이 문제가 해결되는 것처럼 보이지만 (사용합니다 new Date().toString()) 해킹처럼 느껴집니다.

이것을 달성하는 다른 방법이 있습니까? 또는 고유 문자열이 이것을 달성하는 유일한 방법이라면 new Date()? 이외의 제안은 무엇입니까?


$.now()매번 (new Date (). getTime ()) 대신 짧은 표기법을 사용할 수 있습니다 .
Dayson

1
질문 제목이 잘못되었습니다. 이름을 바꾸는 것을 고려해 볼 수 있습니까?
0112

4
다른 답변을 허용되는 답변으로 선택하는 것을 고려 했습니까?
M4N

답변:


241

내가 사용하는 new Date().getTime()같은 밀리 초 내에서 일어나는 여러 요청을하지 않는 한 충돌을 피할 수있는 :

$.get('/getdata?_=' + new Date().getTime(), function(data) {
    console.log(data); 
});

편집 : 이 답변은 몇 살입니다. 여전히 작동하지만 (삭제하지는 않았지만)이를 달성하는 더 나은 방법이 있습니다 . 방법을 선호 하지만 답변은 페이지 수명 동안 모든 요청에 대해 캐싱을 비활성화하려는 경우에도 유용합니다 .


11
Peter J의 답변과 같이 jQuery 가이 작업을 수행하는 것이 더 깨끗하기 때문에 다운 투표를합니다. 솔루션은 작동하지만 장기적으로 유지 관리하기가 더 어렵습니다.
Niklas Wulff 2019 년

11
이 중 어떤 부분에 유지 보수가 필요합니까? jQuery와 비교할 때?
Sunny R Gupta

5
new Date().getTime()코드가 다음과 같이 활용 된다는 점에 주목할 가치가 있습니다 var nocache = new Date().getTime(); var path = 'http://hostname.domain.tld/api/somejsonapi/?cache=' + nocache;. 저 자신을 알아내는 데 몇 분이 걸렸습니다. 물론 ?cacheAPI가 실제로 원하지 않는 표현이 될 수 있습니다.
doubleJ

1
+1 Peter J의 대답 조차도이 답변 에 대한 더 나은 접근 방식은 잘못된 것이 아니며 나쁜 대답이 아닙니다. 나는 DV가 Peter의 것 위에 있기 때문에 DV가 만들어 졌다고 생각합니다. 2013 년 초부터 영업 이익이 SO에 표시되지 않음
Michel Ayres

1
url = url + (-1 === url.indexOf('?') ? '?' : '&') + "__=" + Number(new Date());

513

다음은 사용하는 jQuery 메소드 ($ .get, $ .ajax 등)에 관계없이 향후 모든 AJAX 요청이 캐시되지 않도록합니다.

$.ajaxSetup({ cache: false });

7
조사 (Fiddler)하면 jQuery는 단순히 타임 스탬프를 추가하여 내부적으로 구현합니다 (이 답변의 다른 곳에서 논의 된 것처럼). 나에게 .ajaxSetup 방법은 더 깨끗합니다 (제 생각에는).
Peter J

8
실제로 문서 준비 호출 안에있을 필요는 없습니다.
피터 J

19
왜 전역 적으로 아약스 캐싱을 비활성화해야합니까? 나는 그것이 Jonathan의 답변과 같은 통화별로 수행되어야한다고 생각합니다.
Sunny R Gupta

5
앱에서 작동하는 것 모든 AJAX 호출에 대한 새로운 데이터가 절대적으로 필요할 때마다 상용 앱에서이 방법을 계속 사용합니다. 다른 사람들에게는 캐시 된 데이터가 좋습니다.
피터 J

1
link 설명 : 향후 Ajax 요청에 대한 기본값을 설정하십시오. 사용하지 않는 것이 좋습니다.
itwebdeveloper

319

JQuery의 $ .get ()은 결과를 캐시합니다. 대신에

$.get("myurl", myCallback)

캐싱을 해제 할 수있는 $ .ajax를 사용해야합니다.

$.ajax({url: "myurl", success: myCallback, cache: false});

62
+1 정답입니다. 전 세계적으로 비활성화 된 캐싱에 대한 Peter J의 솔루션은 나쁜 관행 IMO입니다.
Salman von Abbas

7
페이지 / 요청에 대해서만 "글로벌"이라는 점에 유의하십시오.
피터 J

3
+1 : 캐싱은 요청 유형에 따라 다릅니다. 일부 서버 요청에는 캐싱이 필요할 수 있으므로 (서버 데이터가 정적 인 경우) 요청 별로 요청에 따라 캐싱을 선택하는 것이 모든 요청을 끄는 것 보다 낫습니다 .
사라 코딩

1
정답 인 경우 +1-수동 해킹이 아닌 jQuery의 방법을 사용하여 통화별로 캐싱을 방지합니다.
Brendan Hill

2
또 다른 좋은 대답입니다. 전 세계적으로 캐시를 비활성화하는 데 대부분의 시간이 큰 도움이되었다고 말해야합니다. 그것은 모두 응용 프로그램의 디자인 방식에 달려 있습니다. 실버 글 머리 기호는 없지만이 상황에서는 캐싱을위한 부울, 콜백 및 모듈성을위한 URL을 허용하는 기능을 권장합니다. 수동 "해킹"은 괜찮지 만 jQuery를 사용하는 경우 가능할 때마다 해당 기능을 사용하십시오. 이를 통해 이제는 개발이 쉬워 질뿐만 아니라 향후 라이브러리로 업그레이드 할 수 있습니다.
Anthony Mason

24

여기의 모든 답변은 요청 된 URL에 발자국을 남기고 서버의 액세스 로그에 표시됩니다.

부작용이없는 헤더 기반 솔루션이 필요했으며 모든 브라우저에서 웹 페이지 캐싱을 제어하는 ​​방법에 언급 된 헤더를 설정하면 얻을 수 있습니다 . .

적어도 Chrome에서 작동하는 결과는 다음과 같습니다.

$.ajax({
   url: url, 
   headers: {
     'Cache-Control': 'no-cache, no-store, must-revalidate', 
     'Pragma': 'no-cache', 
     'Expires': '0'
   }
});


어리석은 질문 일 수도 있지만 내 아약스가 이미지를 반환하면 이미지가 캐시됩니까? 대규모 Amazon S3 요청을 피하려면?
Marcelo Agimóvel

MarceloAgimóvel, 그것은 내가 믿는 별도의 질문 일 수 있습니다.
Aidin

23

또 다른 방법은 ajax 호출에 대한 응답을 생성하는 코드에서 서버 측에서 캐시 헤더를 제공하지 않는 것입니다.

response.setHeader( "Pragma", "no-cache" );
response.setHeader( "Cache-Control", "no-cache" );
response.setDateHeader( "Expires", 0 );

17
잘못되었습니다. IE에서, 캐시없는 헤더는 XMLHttpRequest 호출에 대해 무시됩니다. stackoverflow.com/questions/244918/… DateTime (또는 내 .ajaxSetup 메소드)은 실제로 작동하는 유일한 솔루션입니다.
피터 J

방금 캐시없는 진언을 붙여 넣었습니다. IE 특유의
말이 아닙니다

2
모든 브라우저에 대한 캐싱을 종료해야합니다. response.setHeader ( "Cache-Control", "max-age = 0, no-cache, no-store, post-check = 0, pre-check = 0");
Chris Broski

13

개인적으로 나는 쿼리 문자열 방법이 서버에서 헤더를 설정하는 것보다 더 안정적이라고 생각합니다-프록시 또는 브라우저가 단순히 캐시하지 않을 것이라는 보장은 없습니다 (일부 브라우저는 다른 브라우저보다 나쁩니다-이름을 지정하지 않음).

나는 일반적으로 사용 Math.random()하지만 날짜를 사용하는 데 아무런 문제가 없습니다 (동일한 값을 두 번 얻을 수있을만큼 빨리 AJAX 요청을해서는 안됩니다).


2
Date (). getTime ()을 Math.random ()과 결합하면 안전한면에 있어야합니다. 참고로 Ext.Ajax는 disableCaching이 지정 될 때 getTime ()도 사용합니다.
vividos

12

설명서에 따라 : http://api.jquery.com/jquery.ajax/

다음 cache과 함께 속성을 사용할 수 있습니다 .

$.ajax({
    method: "GET",
    url: "/Home/AddProduct?",
    data: { param1: value1, param2: value2},
    cache: false,
    success: function (result) {
        // TODO
    }
});

5

물론 "캐시 브레이킹"기술은 작업을 수행하지만 서버가 클라이언트에게 응답을 캐싱해서는 안된다고 표시 한 경우 처음에는 발생하지 않습니다. 경우에 따라 응답을 캐시하는 것이 유익한 경우도 있습니다. 서버가 올바른 데이터 수명을 결정하게하십시오. 나중에 변경할 수도 있습니다. UI 코드의 여러 위치보다 서버에서 수행하는 것이 훨씬 쉽습니다.

물론 서버를 제어 할 수없는 경우에는 도움이되지 않습니다.


5

GET 대신 POST 요청을 사용하는 것은 어떻습니까? (어쨌든 ...)


나는 그것이 더 나은 해결책이라고 생각하지만 슬프게도 (어쨌든) GET 요청 만 할 수 있습니다. 그래서 .. 지금은 새로운 Date (). getTime ()입니다.
Salamander2007

다른 사람들이 배울 수 있도록 답변에 설명을 추가하십시오- POST 요청이 필요합니까?
니코 하세

5

실제 질문은 이것이 캐시되지 않기 위해 왜 필요한지입니다. 항상 변경되어 캐시되지 않아야하는 경우 서버는 자원을 캐시하지 않도록 지정해야합니다. 때때로 변경되는 경우 (자신이 의존하는 리소스 중 하나가 변경 될 수 있기 때문에) 클라이언트 코드에 알 수있는 방법이있는 경우 일부 해시 또는 마지막 수정 날짜에서 계산 된 URL에 더미 매개 변수를 추가 할 수 있습니다. 이러한 리소스 중 (이것은 Microsoft Ajax 스크립트 리소스에서 수행하므로 영구적으로 캐시 될 수 있지만 새 버전은 계속 표시 될 수 있습니다). 클라이언트가 변경 사항을 알 수없는 경우 서버가 HEAD 요청을 올바르게 처리하고 클라이언트에게 캐시 된 버전을 사용할지 여부를 알려주는 올바른 방법이 있어야합니다. 캐시 가능성은 서버 리소스의 속성이므로 임의의 매개 변수를 추가하거나 클라이언트에서 캐시하지 말라고 알려주는 것 같습니다. 서버 측에서 결정해야합니다. 스스로에게 물어볼 또 다른 질문은이 리소스가 실제로 GET을 통해 제공되어야합니까 아니면 POST를 통과해야합니까? 이는 의미론의 문제이지만 보안에 영향을 미칩니다 (서버가 GET을 허용하는 경우에만 작동하는 공격이 있습니다). POST는 캐시되지 않습니다.


6
캐싱 정책을 제어하지 않는 프록시 서버를 통과하는 경우 어떻게합니까? 앱이 매번 새로운 요청을 명시 적으로 수행해야하는 경우 어떻게해야합니까? 사물에 대한 대답은 항상 흑백으로 선명하게 잘라지는 것은 아니며 항상 회색 영역이 있습니다.
7wp

사실, 항상 명확한 것은 아닙니다. 그러나이 답변을 보면서 내 가정에 의문을 제기하고 문제의 근본 원인을 찾도록 이끌었습니다. 모든 사람에게 해당되는 것은 아니지만 도움이되었습니다. 이 글을 읽고 있다면 이것도 고려해야합니다.
Jonathan Tran

ResponseCaching은 기본적으로 60m 서버 측으로 설정되었습니다. No-Cache로 변경하고 클라이언트에서 캐싱을 중지했습니다.
mattygee

4

어쩌면 $ .ajax () 대신 (jQuery를 사용하는 경우처럼 보일 것입니다). http://docs.jquery.com/Ajax/jQuery.ajax#options 및 옵션 "cache"를 살펴보십시오 .

또 다른 방법은 서버 측에서 캐시하는 방법을 보는 것입니다.


1
불행히도, 약간의 조사 후에 $ .ajax () 및 set cache = false를 사용하면 기본적으로 동일한 작업을 수행합니다. jQuery는 쿼리 문자열에 임의의 숫자를 추가하고 기존 쿼리 문자열을 확인하지 않습니다. 따라서 $ .get ()을 사용하면 충분합니다.
Salamander2007

아 좋아요 그것을 시도하지, 그냥 문서에서 그것에 대해 뭔가를 본 기억 :)
finpingvin

$ .ajax를 사용할 필요조차 없습니다. .ajaxSetup을 사용하십시오.
Peter J

3

주어진 훌륭한 답변에 대한 작은 추가 사항 : 자바 스크립트가없는 사용자를 위해 비 백업 백업 솔루션으로 실행하는 경우 어쨌든 해당 서버 측 헤더를 가져와야합니다. 포기하는 사람들을 이해하지만 이것은 불가능하지 않습니다.)

SO에 대한 다른 질문이 있다고 확신하여 적절한 전체 헤더 세트를 제공합니다. 나는 전적으로 유죄 판결을받지 않았다.


3

모바일 Safari 에서 cache옵션 을 사용하는 사람들에게는 $.ajaxSetup()모바일 Safari가 캐시하기 때문에 POST에 타임 스탬프를 사용해야 할 수도 있습니다. 에 대한 설명서에 따르면 $.ajax()(에서 보낸 $.ajaxSetup()) :

캐시를 false로 설정하면 HEAD 및 GET 요청에서만 올바르게 작동합니다. "_ = {timestamp}"를 GET 매개 변수에 추가하여 작동합니다. GET에서 이미 요청한 URL에 POST를 수행 할 때 IE8을 제외하고 다른 유형의 요청에는이 매개 변수가 필요하지 않습니다.

따라서 위에서 언급 한 경우 해당 옵션 만 설정해도 도움이되지 않습니다.


2

기본적으로 cache:false;진행 상황에 따라 내용이 변경 될 것이라고 생각하는 아약스를 추가하십시오 . 그리고 내용이 바뀌지 않는 곳에서 이것을 생략 할 수 있습니다. 이런 식으로 u는 매번 새로운 응답을 얻을 것입니다


2

Internet Explorer의 Ajax 캐싱 : 무엇을하려고하십니까? 세 가지 접근 방식을 제안합니다.

  1. ? date = [timestamp]와 같이 캐시 버스 팅 토큰을 쿼리 문자열에 추가하십시오. jQuery와 YUI에서는이를 자동으로 수행하도록 지시 할 수 있습니다.
  2. GET 대신 POST 사용
  3. 브라우저가 캐시하지 못하도록 특별히 금지하는 HTTP 응답 헤더를 보냅니다.

2

이제 다음과 같이 ajax 요청에서 캐시 옵션을 활성화 / 비활성화하여 쉽게 수행 할 수 있습니다.

$(function () {
    var url = 'your url goes here';
    $('#ajaxButton').click(function (e) {
        $.ajax({
            url: url,
            data: {
                test: 'value'
            },
                cache: true, //cache enabled, false to reverse
                complete: doSomething
            });
        });
    });
    //ToDo after ajax call finishes
    function doSomething(data) {
        console.log(data);
    }
});

3
6 년 후 Jonathan과 동일한 답변을 제공하고 있습니까? ಠ_ಠ
redent84

사람들은 질문이 게시 된 후 6 년이 지났다고 말할 수 있습니다. 그리고 그 질문에 대한 나의 대답은 다른 질문과 다릅니다. 오늘날 그것이 올바른 질문이라는 것은 말할 것도 없습니다. 그러한 질문에 대답하는 것은 지역 사회와 초보자를위한 "구도자"가 아닙니다! 어쨌든 설명을 추가해 주셔서 감사합니다!
Omar El Don

그리고 당신 과이 하나의 차이점은 무엇 입니까? stackoverflow.com/a/735084/469218 ?
redent84

어쩌면 그런 질문을하는 초보자의 관점에서 분명 할 것입니다 !!
Omar El Don


1

@Athasach가 말했듯이 jQuery 문서에 따르면 $.ajaxSetup({cache:false}) GET 및 HEAD 요청 외에는 작동하지 않습니다.

당신은 다시 보내는 것이 좋습니다 Cache-Control: no-cache어쨌든 서버에서 헤더를 . 문제를보다 명확하게 분리 할 수 ​​있습니다.

물론 이것은 프로젝트에 속하지 않은 서비스 URL에는 작동하지 않습니다. 이 경우 클라이언트 코드에서 호출하지 않고 서버 코드에서 타사 서비스를 프록 싱하는 것을 고려할 수 있습니다.


1

.net ASP MVC를 사용하는 경우 엔드 포인트 기능에 다음 속성을 추가하여 컨트롤러 조치에서 캐싱을 사용 불가능하게하십시오.

[OutputCacheAttribute(VaryByParam = "*", Duration = 0, NoStore = true)]

더 자세히 설명해 주시겠습니까? 해당 배열은 AJAX와 어떤 관련이 있습니까?
니코 하세

배열이 아니며 MVC 컨트롤러 작업 의 속성 입니다.
마리우스

0

헤더 추가

headers: {
                'Cache-Control':'no-cache'
            }

다른 사람들이 배울 수 있도록 답변에 설명을 추가하십시오- 헤더를 어디에 추가해야합니까?
니코 하세

-3

Math.random() 요청 URL에 추가


2
결과가 불안정합니다.
aj.toulan

Math.random은 url? _ = [Math.Random ()]과 같은 prameter로만 작동하며 불안정한 결과와 관련이 없습니다.
xiaoyifang

4
당신이 뭘했는지 이해합니다 Math.Random ()이 때로는 같은 숫자를 두 번 줄 것이라고 언급했습니다. 불확실성으로 시스템을 채우면 서로 상단에 추가됩니다.
aj.toulan
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.