programing

클라이언트에 JavaScript 파일을 강제로 새로 고치려면 어떻게 해야 합니까?

goodsources 2022. 9. 13. 22:18
반응형

클라이언트에 JavaScript 파일을 강제로 새로 고치려면 어떻게 해야 합니까?

우리는 현재 비공개 베타판 작업을 진행 중이고, 아직 상당히 빠른 변경 작업을 진행 중이지만, 분명히 사용량이 증가하기 시작함에 따라 이 과정이 느려질 것입니다.단, 새로운 JavaScript 파일로 업데이트를 푸시한 후에도 클라이언트브라우저는 캐시된 버전의 파일을 사용하여 업데이트를 볼 수 없다는 문제가 있습니다.지원 콜에서는 서버로부터 최신 파일을 입수할 수 있도록 리프레쉬를 실시하도록 고객에게 통지하는 것만으로 충분합니다만, 그 전에 처리하는 것이 좋습니다.

현재 우리의 생각은 버전 번호를 JavaScript 파일 이름에 첨부하고 변경이 이루어지면 스크립트의 버전을 증가시키고 모든 참조를 업데이트하는 것입니다.이렇게 하면 작업이 확실히 완료되지만, 각 릴리스의 레퍼런스를 갱신하는 것은 번거로울 수 있습니다.

우리가 이 문제를 처음 해결한 것은 아니라는 것을 확신하기 때문에, 나는 그것을 지역사회에 버리려고 생각했다.코드를 업데이트할 때 클라이언트가 캐시를 업데이트하도록 하려면 어떻게 해야 합니까?위에서 설명한 방법을 사용하는 경우 변경을 간소화하는 프로세스를 사용하고 있습니까?

제가 알기론 일반적인 해결방법은,?<version>src src src를 사용하다

예:

<script type="text/javascript" src="myfile.js?1500"></script>

이 시점에서 모든 스크립트태그에서 이러한 "버전 번호"를 증가시키는 방법은 find-replace보다 더 나은 방법은 없을 것 같습니다.

버전 관리 시스템을 통해 그렇게 할 수 있습니까?대부분의 버전 제어 시스템에는 체크인 시 리비전 번호를 자동으로 삽입하는 방법이 있습니다.

다음과 같이 됩니다.

<script type="text/javascript" src="myfile.js?$$REVISION$$"></script>

물론 이와 같은 더 나은 해결책은 항상 있습니다.

URL에 현재 시간을 추가하는 것은 일반적인 해결책입니다.그러나 웹 서버 수준에서도 관리할 수 있습니다.javascript 파일에 대해 다른 HTTP 헤더를 전송하도록 서버를 구성할 수 있습니다.

예를 들어, 파일을 1일 이내에 강제로 캐시하려면 다음과 같이 전송합니다.

Cache-Control: max-age=86400, must-revalidate

베타판의 경우 사용자가 항상 최신 정보를 얻도록 강제하려면 다음을 사용합니다.

Cache-Control: no-cache, must-revalidate

구글 페이지 속도:정적 리소스의 URL에 쿼리 문자열을 포함하지 마십시오.대부분의 프록시(특히 Squid 버전 3.0까지)는 응답에 Cache-control: public 헤더가 있더라도 URL에 "?"가 있는 리소스를 캐시하지 않습니다.이러한 리소스에 대한 프록시 캐싱을 활성화하려면 정적 리소스에 대한 참조에서 쿼리 문자열을 제거하고 대신 매개 변수를 파일 이름으로 인코딩하십시오.

이 경우 버전을 URL ex: http://abc.com/v1.2/script.js에 포함시키고 apache mod_mod_mod를 사용하여 링크를 http://abc.com/script.js으로 리디렉션할 수 있습니다.버전을 변경하면 클라이언트브라우저가 새 파일을 업데이트합니다.

이 사용법은 수정되었습니다.https://developer.mozilla.org/en-US/docs/Web/HTML/Using_the_application_cache

이 답변은 6년밖에 늦었지만 많은 곳에서 이 답변을 볼 수 없습니다.HTML5는 이 문제를 해결하기 위해 사용되는 애플리케이션 캐시를 도입했습니다.제가 쓰고 있는 새로운 서버 코드가 사람들의 브라우저에 저장된 오래된 자바스크립트가 크래시 되고 있다는 것을 알게 되었기 때문에, 그들의 자바스크립트를 만료시킬 방법을 찾고 싶었습니다.다음과 같은 매니페스트 파일을 사용합니다.

CACHE MANIFEST
# Aug 14, 2014
/mycode.js

NETWORK:
*

사용자가 캐시를 갱신할 때마다 새로운 타임스탬프로 이 파일을 생성합니다.참고로, 이 항목을 추가하면 매니페스트가 지시할 때까지 브라우저는 새로고침되지 않습니다(사용자가 페이지를 새로고침해도 마찬가지).

로드 파라미터로 filesize를 추가하는 것은 어떻습니까?

<script type='text/javascript' src='path/to/file/mylibrary.js?filever=<?=filesize('path/to/file/mylibrary.js')?>'></script>

따라서 파일을 업데이트할 때마다 "filever" 매개 변수가 변경됩니다.

파일을 업데이트하고 업데이트 결과가 동일한 파일 크기일 때는 어떻습니까?확률이 얼마나 되죠?

모든 브라우저가 '?'가 포함된 파일을 캐시하는 것은 아닙니다.가능한 한 많이 캐시되도록 하기 위해 파일 이름에 버전을 포함시켰습니다.

★★★★★★★★★★★★★★★★★★★stuff.js?123 했다stuff_123.js

하였습니다.mod_redirect 생각에) (아파치) to (아파치)have stuff_*.jsstuff.js

오늘날 일반적인 방법은 파일 이름의 일부로 콘텐츠 해시 코드를 생성하여 브라우저, 특히 IE가 javascript 파일 또는 css 파일을 새로고침하도록 강제하는 것입니다.

예를들면,

vendor.a7561fb0e9a071baadb9.js
main.b746e3eb72875af2ca9.js

일반적으로 웹 팩과 같은 빌드 도구의 작업입니다.웹 팩을 사용하고 있는 경우, 시험해 보고 싶은 유저가 있는 경우는, 이하에 상세를 나타냅니다.

ASP의 경우.사용하고 있는 NET 페이지:

전에

<script src="/Scripts/pages/common.js" type="text/javascript"></script>

AFTER(강제 새로고침)

<script src="/Scripts/pages/common.js?ver<%=DateTime.Now.Ticks.ToString()%>" type="text/javascript"></script>

Date Time 추가 중.이제, 틱스는 잘 작동한다.

ASP의 경우.NET 고급 옵션(디버깅/릴리스 모드, 버전):

Js 또는 CSS 파일은 다음과 같이 포함됩니다.

<script type="text/javascript" src="Scripts/exampleScript<%=Global.JsPostfix%>" />
<link rel="stylesheet" type="text/css" href="Css/exampleCss<%=Global.CssPostfix%>" />

Global.JsPostfix 및 Global.CssPostfix는 Global.asax에서 다음 방법으로 계산됩니다.

protected void Application_Start(object sender, EventArgs e)
{
    ...
    string jsVersion = ConfigurationManager.AppSettings["JsVersion"];
    bool updateEveryAppStart = Convert.ToBoolean(ConfigurationManager.AppSettings["UpdateJsEveryAppStart"]);
    int buildNumber = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.Revision;
    JsPostfix = "";
#if !DEBUG
    JsPostfix += ".min";
#endif      
    JsPostfix += ".js?" + jsVersion + "_" + buildNumber;
    if (updateEveryAppStart)
    {
        Random rand = new Random();
        JsPosfix += "_" + rand.Next();
    }
    ...
}

JS 파일에 링크하는 페이지를 생성하는 경우, 간단한 솔루션은 생성된 링크에 파일의 마지막 수정 타임스탬프를 추가하는 것입니다.

이것은 Huppie의 답변과 매우 유사하지만 키워드 대체 없이 버전 관리 시스템에서 작동합니다.또한 파일이 전혀 변경되지 않은 경우에도 캐시를 할 수 없으므로 현재 시간을 추가하는 것보다 더 좋습니다.

PHP의 경우:

function latest_version($file_name){
    echo $file_name."?".filemtime($_SERVER['DOCUMENT_ROOT'] .$file_name);
}

HTML의 경우:

<script type="text/javascript" src="<?php latest_version('/a-o/javascript/almanacka.js'); ?>">< /script>

구조:

에서는, 의 「HTML in 。filepathPHP를 취득합니다.filetime한다.filepath+name+"?"+time 변경의

사용자를 위한 SaaS를 만들고 웹 사이트 페이지에 첨부할 스크립트를 제공하고 있습니다.사용자가 기능을 위해 스크립트를 웹 사이트에 첨부하고 스크립트를 업데이트할 때마다 강제로 버전을 변경할 수 없기 때문에 스크립트와 함께 첨부할 수 없었습니다.

따라서 사용자가 원래 스크립트를 호출할 때마다 새로운 버전의 스크립트를 로드하는 방법을 찾았습니다.

사용자에게 제공되는 스크립트 링크

<script src="https://thesaasdomain.com/somejsfile.js" data-ut="user_token"></script>

스크립트 파일

if($('script[src^="https://thesaasdomain.com/somejsfile.js?"]').length !== 0) {
   init();
} else {
   loadScript("https://thesaasdomain.com/somejsfile.js?" + guid());
}

var loadscript = function(scriptURL) {
   var head = document.getElementsByTagName('head')[0];
   var script = document.createElement('script');
   script.type = 'text/javascript';
   script.src = scriptURL;
   head.appendChild(script);
}

var guid = function() {
    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
        var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
        return v.toString(16);
    });
}

var init = function() {
    // our main code
}

설명:

사용자는 웹사이트에 제공된 스크립트를 첨부하여 jQuery 셀렉터를 사용하여 스크립트에 연결된 고유 토큰이 있는지 확인하고 없는 경우 새로운 토큰(또는 버전)을 사용하여 동적으로 로드합니다.

이는 같은 스크립트를 2회 호출하여 퍼포먼스의 문제가 될 수 있지만 사용자 또는 클라이언트에 제공된 실제 스크립트 링크에 버전을 넣지 않고 강제로 캐시에서 스크립트를 로드하지 않는 문제를 해결합니다.

면책사항:퍼포먼스가 큰 문제가 되는 경우는 사용하지 말아 주세요.

jQuery 함수 getScript는 페이지가 로드될 때마다 js 파일이 실제로 로드되도록 하기 위해 사용할 수도 있습니다.

저는 이렇게 했습니다.

$(document).ready(function(){
    $.getScript("../data/playlist.js", function(data, textStatus, jqxhr){
         startProgram();
    });
});

http://api.jquery.com/jQuery.getScript/ 에서 함수를 체크합니다.

기본적으로는 $.getScript()는 캐시 설정을 false로 설정합니다.그러면 요청 URL에 타임스탬프 쿼리 파라미터가 추가되어 요청 시마다 브라우저가 스크립트를 다운로드하도록 합니다.

동료는 http://www.stefanhayden.com/blog/2006/04/03/css-caching-hack/에 글을 올린 직후에 그 방법에 대한 레퍼런스를 발견했습니다.다른 사람들이 사용하고 있는 것을 보니 효과가 있는 것 같습니다.이 시점에서 모든 스크립트태그에서 이러한 "버전 번호"를 증가시키는 방법은 find-replace보다 더 나은 방법은 없을 것 같습니다.

asp.net MVC 에서는 @DateTime 을 사용할 수 있습니다.js 파일 버전 번호의 UtcNow.ToString().버전 번호가 날짜와 함께 자동으로 변경되며 클라이언트 브라우저가 js 파일을 자동으로 새로 고치도록 강제합니다.저는 이 방법을 사용하고 있고, 이것은 잘 작동합니다.

<script src="~/JsFilePath/JsFile.js?v=@DateTime.UtcNow.ToString()"></script>

해결 방법 중 하나는 리소스를 가져올 때 타임스탬프가 포함된 쿼리 문자열을 URL에 추가하는 것입니다.이를 통해 브라우저는 쿼리 문자열이 포함된 URL에서 가져온 리소스를 캐시하지 않습니다.

브라우저가 이러한 리소스를 캐시하지 않도록 하는 것이 좋습니다.캐시할 가능성이 높지만 파일이 사용 가능하게 되었을 때 브라우저가 새 버전의 파일을 가져오도록 해야 합니다.

가장 일반적인 해결책은 파일 이름 자체에 타임스탬프 또는 리비전 번호를 포함하는 것 같습니다.더 작업이 필요하지만,합니다.왜냐하면 올바른 파일을 요구하기 위해 코드를 수정해야 하기 때문입니다만, 예를 들어 버전7의snazzy_javascript_file.js (예:)snazzy_javascript_file_7.js)는할 때까지 , 그 후 가 "8"을 "fetch"로snazzy_javascript_file_8.js★★★★★★ 。

「 」를 하는 file.js?V=1에 a에 fileV1.js자바스크립트

file.js?V=1새로운 버전의 라이브러리 유틸리티를 사용할 때 다른 JavaScript 파일에 종속 코드가 있을 수 있습니다.

, 는 전전버버고고고고고고고고고고고고고고를 사용하는 것이 훨씬 좋다고 합니다.jQuery.1.3.js할 수 .jQuery.1.1.js필요한 경우 오래된 페이지를 업그레이드할 준비가 될 때까지.

" " 를 사용합니다.GET caching. 브라우저캐싱을 방지합니다.

★★★?v=AUTO_INCREMENT_VERSION브라우저 캐시를 방지하여 캐시된 모든 스크립트를 방지합니다.

ASP 캐시 버스트태그 도우미를 통한 NET Core가 이를 처리하여 파일이 변경될 때까지 브라우저가 캐시된 스크립트/CSS를 유지할 수 있도록 합니다.태그 도우미 asp-delper-version="true"를 스크립트(css) 또는 링크(css) 태그에 추가합니다.

<link rel="stylesheet" href="~/css/site.min.css" asp-append-version="true"/>

Dave Paquet이 캐시 버스트에 대한 좋은 예와 설명을 여기 (페이지 하단의) 캐시 버스트에 대해 설명합니다.

location.disc(true);

https://www.w3schools.com/jsref/met_loc_reload.asp 를 참조해 주세요.

이 문제를 피하기 위해 브라우저의 캐시가 아닌 웹 서버에서 Javascript가 다시 검색되도록 하기 위해 이 코드 행을 동적으로 호출합니다.

프레임워크에 따라 다르지만, Django 1.4는 의 답변의 'greenfelt' 사이트와 유사한 방식으로 작동하는 정적 파일기능을 가지고 있습니다.

한 가지 간단한 방법.htaccess 편집

RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} \.(jpe?g|bmp|png|gif|css|js|mp3|ogg)$ [NC]
RewriteCond %{QUERY_STRING} !^(.+?&v33|)v=33[^&]*(?:&(.*)|)$ [NC]
RewriteRule ^ %{REQUEST_URI}?v=33 [R=301,L]

다음과 같이 파일 이름에 파일 버전을 추가할 수 있습니다.

https://www.example.com/script_fv25.js

fv25 => 파일버전 nr. 25

그리고 .htaccess에 다음 블록을 넣으면 링크에서 버전 부분이 삭제됩니다.

RewriteEngine On
RewriteRule (.*)_fv\d+\.(js|css|txt|jpe?g|png|svg|ico|gif) $1.$2 [L]

마지막 링크는 다음과 같습니다.

https://www.example.com/script.js

PHP와 Javascript를 사용하는 경우, 특히 파일을 여러 번 변경하는 상황에서는 다음 사항이 효과적입니다.따라서 매번 버전을 변경할 수 없습니다.따라서 PHP에서 랜덤 번호를 생성하여 JS 파일의 버전으로 할당하는 것이 좋습니다.

$fileVersion = rand();
<script src="addNewStudent.js?v=<?php echo $fileVersion; ?>"></script>

프론트 엔드 옵션

백엔드의 설정을 변경할 수 없는 분들을 위해 특별히 만든 코드입니다.이 경우 매우 긴 캐시를 방지하는 가장 좋은 방법은 다음과 같습니다.

new Date().getTime()

그러나 대부분의 프로그래머에게 캐시는 몇 분 또는 몇 시간이 걸릴 수 있기 때문에 위의 간단한 코드는 모든 사용자에게 "찾아본 페이지"를 다운로드하도록 강요합니다.이 아이템을 새로고침하지 않고 유지할 수 있는 기간을 지정하기 위해 이 코드를 만들고 아래에 몇 가지 예를 남겼습니다.

// cache-expires-after.js v1
function cacheExpiresAfter(delay = 1, prefix = '', suffix = '') { // seconds
    let now = new Date().getTime().toString();
    now = now.substring(now.length - 11, 10); // remove decades and milliseconds
    now = parseInt(now / delay).toString();
    return prefix + now + suffix;
};

// examples (of the delay argument):
// the value changes every 1 second
var cache = cacheExpiresAfter(1);
// see the sync
setInterval(function(){
    console.log(cacheExpiresAfter(1), new Date().getSeconds() + 's');
}, 1000);

// the value changes every 1 minute
var cache = cacheExpiresAfter(60);
// see the sync
setInterval(function(){
    console.log(cacheExpiresAfter(60), new Date().getMinutes() + 'm:' + new Date().getSeconds() + 's');
}, 1000);

// the value changes every 5 minutes
var cache = cacheExpiresAfter(60 * 5); // OR 300

// the value changes every 1 hour
var cache = cacheExpiresAfter(60 * 60); // OR 3600

// the value changes every 3 hours
var cache = cacheExpiresAfter(60 * 60 * 3); // OR 10800

// the value changes every 1 day
var cache = cacheExpiresAfter(60 * 60 * 24); // OR 86400

// usage example:
let head = document.head || document.getElementsByTagName('head')[0];
let script = document.createElement('script');
script.setAttribute('src', '//unpkg.com/sweetalert@2.1.2/dist/sweetalert.min.js' + cacheExpiresAfter(60 * 5, '?'));
head.append(script);

// this works?
let waitSwal = setInterval(function() {
    if (window.swal) {
        clearInterval(waitSwal);
        swal('Script successfully injected', script.outerHTML);
    };
}, 100);

가장 심플한 솔루션브라우저가 캐시되지 않도록 합니다.현재 시간(ms)을 쿼리로 추가합니다.

(아직 베타 버전이기 때문에 성능을 최적화하지 않는 타당한 이유를 제시할 수 있습니다.하지만 YMMV는 여기 있습니다.)

아래는 나에게 효과가 있었다.

<head>
<meta charset="UTF-8">
<meta http-equiv="cache-control" content="no-cache, must-revalidate, post-check=0, pre-check=0" />
<meta http-equiv="cache-control" content="max-age=0" />
<meta http-equiv="expires" content="0" />
<meta http-equiv="expires" content="Tue, 01 Jan 1980 1:00:00 GMT" />
<meta http-equiv="pragma" content="no-cache" />
</head>

오래된 자바스크립트 파일과 새로운 자바스크립트 파일의 경합을 방지하기 위한 간단한 트릭입니다.즉, 다음과 같습니다.충돌이 발생하여 오류가 발생하면 Ctrl+F5 키를 누르라는 메시지가 나타납니다.

페이지 맨 위에 다음과 같은 내용을 추가합니다.

<h1 id="welcome"> Welcome to this page <span style="color:red">... press Ctrl-F5</span></h1>

처럼 보인다

여기에 이미지 설명 입력

다음 javascript 행이 페이지를 로드할 때 마지막으로 실행되도록 합니다.

document.getElementById("welcome").innerHTML = "Welcome to this page"

에러가 발생하지 않는 경우는, 상기의 환영 인사말은 거의 표시되지 않고, 거의 즉시 로 대체됩니다.

여기에 이미지 설명 입력

이 작업은 .htaccess를 사용하여 수행할 수 있습니다.

.htaccess 파일에 다음 행을 추가합니다.

# DISABLE CACHING
<IfModule mod_headers.c>
  <FilesMatch "\.js$">
      Header set Cache-Control "no-store, max-age=0"
  </FilesMatch>
</IfModule>
<script>  
  var version = new Date().getTime();  
  var script = document.createElement("script");  
  script.src = "app.js?=" + version;  
  document.body.appendChild(script);  
</script>

위의 답변이 너무 많은 곳에 이미 게시되어 있는 경우에는 삭제해도 됩니다.

언급URL : https://stackoverflow.com/questions/32414/how-can-i-force-clients-to-refresh-javascript-files

반응형