본문 바로가기

web

[JS][HTML] 브라우저 이미지 캐싱 피하기

브라우저 이미지 캐싱 피하기

요약 : 요청 url에 ? 쿼리를 추가한다.



프로필 사진을 변경하는 기능을 구현하던 중, 프로필 사진 변경요청에서 성공적인 응답을 받으면 프로필사진 <img>태그만을 reload 하는 기능을 구현하였습니다.


<img>태그의 src속성을 다시 초기화하면 될줄 알았지만, 이는 동작하지 않았습니다. 개발자 콘솔의 네트워크탭을 확인해보니, 아얘 서버에 있는 프로필 image에 접근하지 않는 현상을 발견하였습니다.


이유는 브라우저가 이미지를 캐싱하기때문입니다.


브라우저는 네트워크 성능 향상을 위해, 해당 페이지에서 요청한, 

image, file, js, css등을 캐싱하여 사용합니다.

(원래 몰랐습니다 TT)



아래의 사진은 크롬의 인터넷 사용기록 삭제 기능입니다.

여기서 보면, 캐시된 이미지 또는 파일 이라는 탭이 있습니다.



이와같이 브라우저는 사용되는 파일등을 캐싱합니다. 그래서 이미 요청한 image경로에 다시, 요청을 보낸다면 브라우저는 이미 캐싱해 두었던, 사진을 사용할뿐 새로운 요청을 보내지 않습니다.

이렇게 캐싱을 사용할 경우, 사용자의 웹 경험이 굉장히 쾌적해 지지만, 개발자의 입장에선 문제가 발생할 수 있습니다.



아래의 코드는 프로필사진을 서버에 업로드 하여, 변경이 성공적으로 완료되었을 경우, 현재 페이지의 프로필사진만을 리로드 하는 코드입니다. 여기서 문제가 발생합니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
$.ajax({
            url: "/upload/image/",
            data: formData,
            processData: false,
            contentType: false,
            type: 'POST',
            success: function(data) {
                $(".profile-pic").attr("src", $(".profile-pic").attr("src"));
                alert("변경이 완료되었어요.");
            },
            error: function(data) {
                alert("변경에 실패했어요. TT")
            }
})
cs


부라우저의 이미지의 캐싱사실을 알지못한 개발자는 굉장히 당황할 것 입니다.  맞는 로직이지만, 생각한 대로 동작하지 않으니까요.

(저도 그랬습니다.)


이 경우, 브라우저는 src속성을 다시 초기화했음에도 새로운 경로로 image를 요청하지 않고, 전에 요청해 두었던 경로와 같으므로 캐싱된 image를 사용합니다. 결과적으로 서버에서는 자신의 프로필 image가 변경되었지만, 사용자는 그 사실을 F5를 눌러 페이지를 리로드 한 뒤에야 확인 할 수 있습니다. 


프로필사진을 변경한뒤, 페이지 전체를 리로드 하는 방법도 있지만, 개발자입장에서는 이미지만을 리로드 하고 싶을겁니다.


이럴 경우 조금의 꼼수 일수 있지만, image경로에 쿼리를 붙여 요청하는 방법이 있습니다. 


아래와 같이 "?"를 경로끝에 붙여 요청하였습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
$.ajax({
            url: "/upload/image/",
            data: formData,
            processData: false,
            contentType: false,
            type: 'POST',
            success: function(data) {
                $(".profile-pic").attr("src", $(".profile-pic").attr("src"+ "?");
                alert("변경이 완료되었어요.");
            },
            error: function(data) {
                alert("변경에 실패했어요. TT")
            }
})
cs



이 방법을 사용할 경우, 브라우저는 캐싱한 이미지 경로로 인식하지 않기때문에 뜻하는 바를 이룰 수 있습니다.