Microsoft MVP성태의 닷넷 이야기
.NET Framework: 218. WCF REST 서비스 - 웹 브라우저 측 Ajax 호출 캐시 [링크 복사], [링크+제목 복사],
조회: 30308
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일
 
(연관된 글이 2개 있습니다.)
WCF REST 서비스 - 웹 브라우저 측 Ajax 호출 캐시

미리 말씀드리면, 이 문제는 WCF REST 서비스에 국한되지 않습니다. 단지, 서버 측 서비스의 테스트 환경이 WCF REST 서비스였다는 데 의미가 있을 뿐이지만, 어쩌면 WCF REST 서비스로 구현하면서도 역시 한 번쯤은 접할 수 있는 문제여서 제목을 이렇게 지은 것입니다. (사실... 제가 헤맸습니다. ^^;)

문제 현상은 이렇습니다. 인터넷 익스플로러의 경우, 임시 저장 파일을 쓰는 규칙이 아래 그림에서처럼 "Automatically"로 기본 설정되어 있습니다.

local_web_cache_with_ajax_call_1.png

이런 상태에서 클라이언트 측에 내려가는 웹 페이지(예를 들어, default.aspx)에서 Ajax 호출을 반복적으로 하게 되는 코드(예를 들어, 3초마다)를 작성하면 어떻게 될까요?

function ajaxJson(httpMethod, method, data, callback, error) {
    var url = "./AjaxWCFService/" + method;
    $.ajax({
        url: url,
        data: data,
        type: httpMethod,
        processData: true,
        contentType: "application/json",
        timeout: 1000 * 10,
        dataType: "json",
        success: callback,
        error: error
    });
}

function GetMyListResponse(result) 
{
    setTimeout(function () {
        CallGetAgentList();
    }, 1000 * 3);
}

function CallGetAgentList() 
{
    ajaxJson("GET", "GetMyList", "", GetMyListResponse, GetMyListResponse);
}

CallGetAgentList();

넵, 맞습니다. 위의 호출은 단 한 번만 호출되고 이후의 호출에 대해서는 브라우저 임의 재량에 맞겨지게 됩니다. (대개의 경우, 서버로의 호출이 발생되지 않습니다.) 물론, 이런 경우 브라우저 설정 값이 "Automatically"가 아닌 (대부분의 개발자 컴퓨터의 웹 브라우저 설정인) "Every time I visit the webpage"라고 설정되어 있으면 3초마다 호출이 발생합니다. 따라서, 개발자는 테스트가 잘 되는데, 고객 측의 컴퓨터에서는 이상 현상이 목격되는 것이죠. ^^

이때의 호출을 Fiddler로 가로채면 다음과 같은 식으로 나옵니다.

---------- 요청 ----------
GET http://testpc:7905/AjaxWCFService/GetMyList HTTP/1.1
Referer: http://testpc:7905/Test.aspx
Content-Type: application/json
X-Requested-With: XMLHttpRequest
Accept: application/json, text/javascript, */*
Accept-Language: ko
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; ..[생략]...)
Host: testpc:7905
Connection: Keep-Alive

---------- 응답 ----------
HTTP/1.1 200 OK
Cache-Control: private
Content-Length: 102
Content-Type: application/json; charset=utf-8
Server: Microsoft-IIS/7.5
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?QzpcSmVubmlmZXJcTmV0U2xhXFdlYlxBamF4V2ViU2VydmljZVxHZXRBZ2VudExpc3Q=?=
X-Powered-By: ASP.NET
Date: Fri, 27 May 2011 16:28:05 GMT

...[json 포맷의 데이터]...

이러한 캐시 방지를 위해서 WCF REST 서비스 메서드 측에서는 캐시 정책에 변화를 줄 수 있는 옵션을 주어야 합니다.

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
public class AjaxWCFService : IAjaxWCFService
{
    [WebGet(ResponseFormat = WebMessageFormat.Json)]
    public string GetMyList()
    {
        HttpContext.Current.Response.Expires = 0;
        return "....";
    }
}

위와 같이 변경해 주어도, 여전히 캐시가 되는 사용자가 있는데요. 어쩔 수 없습니다. 이미 캐시된 것을 반복사용하고 있는 것이기 때문에 브라우저 자체의 만료 기간이 지날 때까지 기다리든가, 아니면 사용자 PC에서 직접 임시 파일을 지워주어야 합니다.

일단, 이런 식으로 "Expires == 0"이 지정 되어 응답이 내려가면 다음과 같이 곧바로 만료가 되도록 Expires 헤더값이 지정됩니다.

HTTP/1.1 200 OK
Cache-Control: private
Content-Length: 2
Content-Type: application/json; charset=utf-8
Expires: Fri, 27 May 2011 16:36:16 GMT
Server: Microsoft-IIS/7.5
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?QzpcSmVubmlmZXJcTmV0U2xhXFdlYlxBamF4V2ViU2VydmljZVxHZXRBZ2VudExpc3Q=?=
X-Powered-By: ASP.NET
Date: Fri, 27 May 2011 16:36:18 GMT

...[json 포맷의 데이터]...

아하~~~ 결국 Expires 헤더를 조정하는 것이니까, Expires = 0;뿐만 아니라 다음과 같이 다양한 메서드를 호출해도 효과는 동일하게 적용된다는 것이군요. ^^

HttpContext.Current.Response.Cache.SetExpires(DateTime.MinValue);




[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]

[연관 글]






[최초 등록일: ]
[최종 수정일: 6/27/2021]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
by SeongTae Jeong, mailto:techsharer at outlook.com

비밀번호

댓글 작성자
 



2011-06-23 10시37분
브라우저 cache 관련해서 다음의 글을 읽어보시면 도움이 될 것입니다. ^^

Caching Improvements in Internet Explorer 9
; (broken) http://blogs.msdn.com/b/ie/archive/2010/07/14/caching-improvements-in-internet-explorer-9.aspx
; https://all-markup-news.com/caching-improvements-in-internet-explorer-9/
정성태

... 121  122  123  124  125  126  127  128  129  130  131  [132]  133  134  135  ...
NoWriterDateCnt.TitleFile(s)
1755정성태9/22/201434193오류 유형: 241. Unity Web Player를 설치해도 여전히 설치하라는 화면이 나오는 경우 [4]
1754정성태9/22/201424525VC++: 80. 내 컴퓨터에서 C++ AMP 코드가 실행이 될까요? [1]
1753정성태9/22/201420543오류 유형: 240. Lync로 세미나 참여 시 소리만 들리지 않는 경우 [1]
1752정성태9/21/201440995Windows: 100. 윈도우 8 - RDP 연결을 이용해 VNC처럼 사용자 로그온 화면을 공유하는 방법 [5]
1751정성태9/20/201438885.NET Framework: 464. 프로세스 간 통신 시 소켓 필요 없이 간단하게 Pipe를 열어 통신하는 방법 [1]파일 다운로드1
1750정성태9/20/201423807.NET Framework: 463. PInvoke 호출을 이용한 비동기 파일 작업파일 다운로드1
1749정성태9/20/201423718.NET Framework: 462. 커널 객체를 위한 null DACL 생성 방법파일 다운로드1
1748정성태9/19/201425355개발 환경 구성: 238. [Synergy] 여러 컴퓨터에서 키보드, 마우스 공유
1747정성태9/19/201428361오류 유형: 239. psexec 실행 오류 - The system cannot find the file specified.
1746정성태9/18/201426000.NET Framework: 461. .NET EXE 파일을 닷넷 프레임워크 버전에 상관없이 실행할 수 있을까요? - 두 번째 이야기 [6]파일 다운로드1
1745정성태9/17/201422964개발 환경 구성: 237. 리눅스 Integration Services 버전 업그레이드 하는 방법 [1]
1744정성태9/17/201430973.NET Framework: 460. GetTickCount / GetTickCount64와 0x7FFE0000 주솟값 [4]파일 다운로드1
1743정성태9/16/201420936오류 유형: 238. 설치 오류 - Failed to get size of pseudo bundle
1742정성태8/27/201426914개발 환경 구성: 236. Hyper-V에 설치한 리눅스 VM의 VHD 크기 늘리는 방법 [2]
1741정성태8/26/201421295.NET Framework: 459. GetModuleHandleEx로 알아보는 .NET 메서드의 DLL 모듈 관계파일 다운로드1
1740정성태8/25/201432464.NET Framework: 458. 닷넷 GC가 순환 참조를 해제할 수 있을까요? [2]파일 다운로드1
1739정성태8/24/201426463.NET Framework: 457. 교착상태(Dead-lock) 해결 방법 - Lock Leveling [2]파일 다운로드1
1738정성태8/23/201422000.NET Framework: 456. C# - CAS를 이용한 Lock 래퍼 클래스파일 다운로드1
1737정성태8/20/201419689VS.NET IDE: 93. Visual Studio 2013 동기화 문제
1736정성태8/19/201425535VC++: 79. [부연] CAS Lock 알고리즘은 과연 빠른가? [2]파일 다운로드1
1735정성태8/19/201418128.NET Framework: 455. 닷넷 사용자 정의 예외 클래스의 최소 구현 코드 - 두 번째 이야기
1734정성태8/13/201419778오류 유형: 237. Windows Media Player cannot access the file. The file might be in use, you might not have access to the computer where the file is stored, or your proxy settings might not be correct.
1733정성태8/13/201426258.NET Framework: 454. EmptyWorkingSet Win32 API를 사용하는 C# 예제파일 다운로드1
1732정성태8/13/201434388Windows: 99. INetCache 폴더가 다르게 보이는 이유
1731정성태8/11/201426970개발 환경 구성: 235. 점(.)으로 시작하는 파일명을 탐색기에서 만드는 방법
1730정성태8/11/201422077개발 환경 구성: 234. Royal TS의 터미널(Terminal) 연결에서 한글이 깨지는 현상 해결 방법
... 121  122  123  124  125  126  127  128  129  130  131  [132]  133  134  135  ...