본문 바로가기
Programming/Languages (Java, etc)

js, css, html 파일 웹 브라우저 캐싱 방지 - 쿼리 스트링

by kghworks 2022. 3. 4.
  • 문제
  • 원인
  • 해결책
  • 참고

문제

 웹 소스들 (html, js, css)에 수정을 하여 서버에 반영해도, 브라우저 상에서 반영이 안 되는 경우가 있습니다.

 

 운영 서비스일 때는 이 문제가 더 심각합니다. 새로운 버전을 만들어 서버에 배포를 했어도, 실제 브라우저에서는 개발자 도구를 열어봐도 이전 javascript파일 (기타 정적 파일들, css 등)을 로딩하는 경우가 발생하는 것입니다.


원인

 웹브라우저는 js, css파일을 캐싱해놓고, 동일한 url을 요청한다면 캐싱해둔 소스(이전 소스)를 가져옵니다.  수정한 파일을 서버에 올린다 한들 브라우저는 캐싱되어있는 동일한 url의 소스가 있는 한 새로운 소스를 가져오지 않습니다.

 

 그니까 브라우저가 캐싱하는 것은 문제가 아니고, 캐싱해놓고 내가 새로 올린 파일은 애초에 쳐다도 안 보는 것이 문제인 것입니다.

 

 브라우저의 캐시를 지우면 해결됩니다. 문제는 서비스되고 있는 웹사이트의 경우입니다. 이 때는 패치가 있을 때마다 사용자들에게 "브라우저에서 캐시 삭제 한 번씩 해주세요." 하고 공지해야 합니다. 말이 안 됩니다. 이런 사이트를 본 적도 없고.

 


해결책

 2가지 근본적인 해결책이 있습니다. 핵심은 새로운 url을 요청해 캐싱된 파일을 불러오지 못하도록 하는 것입니다.

 

1. 파일명 수정

 

수정 전

 

<script type="text/javascript" src="/scripts/common1.js?"></script>

 

수정 후 

 

<script type="text/javascript" src="/scripts/common2.js?"></script>

 

 파일의 버전이 바뀔 때마다 파일명을 수정해주는 것입니다. 자주 변경하는 파일이라면 번거로워지니 다음 방법을 추천합니다.

 

2. 쿼리 스트링 (query string)

 

 파일명 뒤에 버전 정보를 담은 쿼리 스트링을 넣어주는 방법이 있습니다. 파일명을 바꾸지 않아도 되므로 덜 번거롭겠죠.

 

수정 전

 

<script type="text/javascript" src="/scripts/common.js?v=1.0"></script>

 

수정 후

 

<script type="text/javascript" src="/scripts/common.js?v=1.1"></script>

 

 자주 수정이 들어가는 파일의 경우 버전을 바꿔주는 일이 많아집니다. 그러므로 js코드, jstl 등을 이용하여 아래와 같이 동적으로 난수를 발생하여 버전 정보에 할당해주는 방법도 있긴 합니다.

 

<script type="text/javascript">

    let scriptURL = "/scripts/common.js.js?v="+Math.random();
    let scriptElement = document.createElement("script");
    scriptElement.src = scriptURL;
    document.head.appendChild(scriptElement);

</script>

 

 실제 브라우저에서 보면 매번 다른 쿼리 스트링을 생산하면서 javascript를 불러옵니다.

 

 

 프로그램 입장에선 동적으로 url을 만드는 로직이 한번 더 들어가는 것이므로 번거롭더라도 개발자가 수기로 버전을 명시하여 바꿔주는 것이 좋을 것으로 판단됩니다.

 

 

3. html 메타태그

 

 추가적으로 html의 캐싱을 방지할 수 있습니다. 만일 javascript import구문이 html 안에 있다면 해당 html 내용도 캐싱이 되면 안 될 것입니다. 아래와 같은 메타태그를 헤더에 포함하여 방지할 수 있습니다.

 

<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />

 

  • no-cache : 캐시된 복사본을 사용자에게 보여주기 이전에, 재검증을 위한 요청을 원 서버로 보내도록 강제
  • no-store : 캐시는 클라이언트 요청 혹은 서버 응답에 관해서 어떤 것도 저장 안 함
  • must-revalidate : 캐시는 사용하기 이전에 기존 리소스의 상태를 반드시 확인해야 하며 만료된 리소스는 사용되어서는 안 됨

 출처 : MDN web docs Cache-Control

 


참고

 

https://developer.mozilla.org/ko/docs/Web/HTTP/Headers/Cache-Control

 

Cache-Control - HTTP | MDN

Cache-Control 일반 헤더 필드는 요청과 응답 내의 캐싱 메커니즘을 위한 디렉티브를 정하기 위해 사용됩니다. 캐싱 디렉티브는 단방향성이며, 이는 요청 내에 주어진 디렉티브가 응답 내에 주어

developer.mozilla.org

 

댓글