투케이2K

569. (javaScript) 자바스크립트 동적 js 파일 추가 및 외부 js 파일 로드 시 타임스탬프 추가해 캐시 초기화 수행 - QueryString 쿼리 스트링 추가 본문

JavaScript

569. (javaScript) 자바스크립트 동적 js 파일 추가 및 외부 js 파일 로드 시 타임스탬프 추가해 캐시 초기화 수행 - QueryString 쿼리 스트링 추가

투케이2K 2026. 7. 9. 19:28
728x90
반응형

[개발 환경 설정]

개발 툴 : Edit++ / Vscode

개발 언어 : JavaScript

 

[소스 코드]

-----------------------------------------------------------------------------------------
[사전 설명 및 설정 사항]
-----------------------------------------------------------------------------------------

- 개발 환경 : Web


- 개발 기술 : JavaScript / js / 라이브러리 / 캐시 초기화


- 사전) 👉 js 파일이나 css 파일에 타임스탬프를 추가 하는 이유 간략 설명 : 

  >> JS 파일이나 CSS 파일 뒤에 타임스탬프 (또는 버전) 를 붙이는 가장 큰 이유는 브라우저 캐시 (Cache) 를 제어하기 위해서입니다.

  >> 브라우저는 성능 향상을 위해 한 번 다운로드한 JS/CSS 를 캐시에 저장합니다.

  >> 서버에서 common.js 를 수정하여 배포했을 경우 사용자의 브라우저는 이미 캐시된 파일을 사용하므로 예전 common.js 를 사용할 수 있습니다.

  >> JS 파일이나 CSS 파일 뒤에 타임스탬프 (또는 버전) 를 붙이면 브라우저는 URL 전체를 기준으로 캐시를 관리하므로 서로 다른 파일로 인식해 다시 다운로드합니다.

-----------------------------------------------------------------------------------------





-----------------------------------------------------------------------------------------
[소스 코드]
-----------------------------------------------------------------------------------------

<!DOCTYPE HTML>
<html lang="ko" translate="no">
<head>
    <title>javaScriptTest</title>

    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">

    <!-- [반응형 구조 만들기] -->
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no">

    <!-- [Chrome / Edge (Chromium)에서 자동 번역 기능을 완전히 비활성화] -->
    <meta name="google" content="notranslate">

    

    <!-- 내부 CSS 스타일 지정 -->
    <style>

        html, body {
            width: 100%;
            height: 100%;
            margin : 0 auto;
            padding : 0;
            border : none;
            background-color: #666;
        }

    </style>





    <!-- ✅ [jquery : CDN 주소 설정] --> 
    <!-- <script src="https://code.jquery.com/jquery-latest.min.js"></script> -->







    <!-- ✅ [동적으로 로드 될 스크립트 id : 동적 src 지정] -->
    <script id="cdnScript"></script>







    <!-- [자바스크립트 코드 지정] -->
    <script type="module">    


    // -----------------------------------------------------------------
    // ✅ [Window.onload 웹 브라우저 로드 완료]
    // -----------------------------------------------------------------
    window.onload = async function() {
        console.log("[window onload] : [html 최초 로드 및 이벤트 상시 대기 실시] : [start]");

        try {

            // ------------------------------------------------
            // 🟦 JS 파일 뒤에 타임스탬프를 붙이는 이유 간략 설명
            // ------------------------------------------------ 
            /*
            1. 브라우저 캐시를 강제로 무효화(Cache Busting) 하기 위해서입니다.
            */
            // ------------------------------------------------ 



            // ------------------------------------------------
            // 🟦 자바스크립트로 동적으로 script 태그 생성
            // ------------------------------------------------
            // 👉 해당 방식으로 추가한 경우 개발자 콘솔 > 요소 및 네트워크 영역에서 로드 된 것 확인 (소스 영역은 초기 코드가 표시 됩니다.)
            // ------------------------------------------------   
            // 👉 Promise 방식으로 로드 콜백 확인 후 코드 사용 수행
            // ------------------------------------------------   
            //*
            const loadedScripts = new Map();

            let loadScriptCallback = function(url){

                return new Promise((resolve, reject) => { 

                    let loadFlag = false;

                    // 이미 로드 성공한 경우
                    if (loadedScripts.has(url)) {
                        if (loadedScripts.get(url) === true){
                            console.log('loadScriptCallback : 이미 로드됨 : ', url);
                            
                            loadFlag = true;

                            resolve();
                        }                    
                    }

                    if (loadFlag === false){

                        const script = document.createElement('script');
                    
                        //script.src = `${url}`; // 👉 일반 URL 지정
                        script.src = `${url}?v=${Date.now()}`; // 👉 동적 타임 스탬프 추가
                    
                        script.onload = () => {
                            console.log('loadScriptCallback : 스크립트 로드 성공 : ', url);

                            loadedScripts.set(url, true); // 👉 Map 에 로드 성공 추가

                            resolve();
                        };
                        
                        script.onerror = (event) => {
                            console.error('loadScriptCallback : 스크립트 로드 실패 : ', event);

                            loadedScripts.set(url, true); // 👉 Map 에 로드 실패 추가

                            reject(new Error(`스크립트 로드 실패 : ${url}`));
                        };

                        document.head.appendChild(script);

                    }
                                    
                });

            };

            
            loadScriptCallback(`https://code.jquery.com/jquery-latest.min.js`)
                .then(() => {
                    console.log('라이브러리 동작 테스트 : ', $.type("TWOK"));
                })

                .catch((error) => {
                    console.error('라이브러리 로드 중 오류 발생 : ', error.message);
                });


            setTimeout(() => {

                    loadScriptCallback(`https://code.jquery.com/jquery-latest.min.js`)
                        .then(() => {
                            console.log('라이브러리 동작 테스트 : ', $.type("TWOK"));
                        })
                        .catch((error) => {
                            console.error('라이브러리 로드 중 오류 발생 : ', error.message);
                        });       

                  }, 3000);
            // */



            // ------------------------------------------------
            // 🟦 자바스크립트로 동적으로 script 태그 생성
            // ------------------------------------------------
            // 👉 해당 방식으로 추가한 경우 개발자 콘솔 > 요소 및 네트워크 영역에서 로드 된 것 확인 (소스 영역은 초기 코드가 표시 됩니다.)
            // ------------------------------------------------   
            // 👉 async await 방식 사용 후 map 저장 된 데이터 확인 방법
            // ------------------------------------------------ 
            /*
            const loadedScripts = new Map();

            let loadScriptAwait = async function(url){
                                
                // 이미 로드 성공한 경우
                if (loadedScripts.has(url)) {
                    if (loadedScripts.get(url) === true){
                        console.log('loadScriptAwait : 이미 로드됨 : ', url);
                        return true;
                    }                    
                }
                
                
                try {

                    await new Promise((resolve, reject) => {

                        const script = document.createElement('script');

                        //script.src = `${url}`; // 👉 일반 URL 지정
                        script.src = `${url}?v=${Date.now()}`; // 👉 동적 타임 스탬프 추가                        

                        script.onload = () => {
                            console.log('loadScriptAwait : 스크립트 로드 성공 : ', url);
                            resolve();
                        };

                        script.onerror = () => {
                            console.error('loadScriptAwait : 스크립트 로드 실패 : ', event);

                            reject(new Error(`스크립트 로드 실패: ${url}`));
                        };                        

                        document.head.appendChild(script);
                    });

                    loadedScripts.set(url, true);

                    return true;

                } catch (error) {

                    console.error(error);

                    loadedScripts.set(url, false);

                    return false;
                }
            };

            
            const result_1 = await loadScriptAwait('https://code.jquery.com/jquery-latest.min.js');

            if (result_1) {
                console.log($.type("TWOK"));
            }


            const result_2 = await loadScriptAwait('https://code.jquery.com/jquery-latest.min.js');

            if (result_2) {
                console.log($.type("TWOK"));
            }
            // */



            // ------------------------------------------------
            // 🟦 자바스크립트로 script id 지정 후 src 주소 설정
            // ------------------------------------------------
            // 👉 해당 방식으로 추가한 경우 개발자 콘솔 > 요소 및 네트워크 영역에서 로드 된 것 확인 (소스 영역은 초기 코드가 표시 됩니다.)
            // ------------------------------------------------ 
            /*
            const loadedScripts = new Map();

            let settingScriptCallback = function(id, url){
                
                return new Promise((resolve, reject) => { 

                    let loadFlag = false;

                    // 이미 로드 성공한 경우
                    if (loadedScripts.has(url)) {
                        if (loadedScripts.get(url) === true){
                            console.log('loadScriptCallback : 이미 로드됨 : ', url);
                            
                            loadFlag = true;

                            resolve();
                        }                    
                    }

                    if (loadFlag === false){

                        const script = document.getElementById(id); // 👉 script id 지정
                    
                        //script.src = `${url}`; // 👉 일반 URL 지정
                        script.src = `${url}?v=${Date.now()}`; // 👉 동적 타임 스탬프 추가
                    
                        script.onload = () => {
                            console.log('settingScriptCallback : 스크립트 로드 성공 : ', url);

                            loadedScripts.set(url, true); // 👉 Map 에 로드 성공 추가

                            resolve();
                        };
                        
                        script.onerror = (event) => {
                            console.error('settingScriptCallback : 스크립트 로드 실패 : ', event);

                            loadedScripts.set(url, true); // 👉 Map 에 로드 실패 추가

                            reject(new Error(`스크립트 로드 실패 : ${url}`));
                        };

                    }
                                    
                });

            };


            settingScriptCallback('cdnScript', `https://code.jquery.com/jquery-latest.min.js`)
                .then(() => {
                    console.log('라이브러리 동작 테스트 : ', $.type("TWOK"));
                })
                .catch((error) => {
                    console.error('라이브러리 로드 중 오류 발생 : ', error.message);
                });


            setTimeout(() => {

                    settingScriptCallback('cdnScript', `https://code.jquery.com/jquery-latest.min.js`)
                        .then(() => {
                            console.log('라이브러리 동작 테스트 : ', $.type("TWOK"));
                        })
                        .catch((error) => {
                            console.error('라이브러리 로드 중 오류 발생 : ', error.message);
                        });       

                }, 3000);
            // */


        }
        catch (exception) {
            console.error("[window onload] : [Exception] : ❌ 예외 상황 발생 : ", exception);
        }

    }; 
      
    </script>


</head>


<body>

</body>

</html>

-----------------------------------------------------------------------------------------





-----------------------------------------------------------------------------------------
[참고 사이트]
-----------------------------------------------------------------------------------------

▶️ 194. (javascript/자바스크립트) 외부 js , css 파일 로드 시 QueryString 쿼리 스트링 추가 및 캐시 초기화 실시간 반영 방법

https://kkh0977.tistory.com/2416

https://blog.naver.com/kkh0977/222860079651?trackingCode=blog_bloghome_searchlist


▶️ 106. (html/css/javascript/jquery) 이미지 태그에 이미지 파일 (jpg, png) 로드 시 확장명 뒤에 QueryString 쿼리 스트링 추가 방법

https://kkh0977.tistory.com/4792

https://blog.naver.com/kkh0977/223246008043?trackingCode=blog_bloghome_searchlist


▶️ 76. (javascript/자바스크립트) object innerHTML 사용해 다른 html 파일 내부에 로드 실시

https://kkh0977.tistory.com/911

https://blog.naver.com/kkh0977/222411584202?trackingCode=blog_bloghome_searchlist


▶️ 43. (javascript/자바스크립트) window ready, window onload 구현 및 코드 차이점 설명 

https://kkh0977.tistory.com/841

https://blog.naver.com/kkh0977/222391324766?trackingCode=blog_bloghome_searchlist

-----------------------------------------------------------------------------------------
 
728x90
반응형
Comments