Programing

클라이언트가 JavaScript 파일을 새로 고치도록하려면 어떻게해야합니까?

lottogame 2020. 10. 4. 10:13
반응형

클라이언트가 JavaScript 파일을 새로 고치도록하려면 어떻게해야합니까?


우리는 현재 비공개 베타로 작업 중이므로 상당히 빠르게 변경하는 과정에 있습니다. 분명히 사용량이 증가하기 시작함에 따라이 프로세스를 늦출 것입니다. 즉, 우리가 겪고있는 한 가지 문제는 새 JavaScript 파일로 업데이트를 푸시 한 후에도 클라이언트 브라우저가 여전히 파일의 캐시 된 버전을 사용하고 업데이트를 볼 수 없다는 것입니다. 분명히 지원 요청시 ctrlF5서버에서 최신 파일을받을 수 있도록 새로 고침 을 수행하도록 간단히 알릴 수 있지만 그 전에 처리하는 것이 좋습니다.

현재 우리의 생각은 JavaScript 파일의 이름에 버전 번호를 붙이고 변경이 이루어지면 스크립트의 버전을 높이고 모든 참조를 업데이트하는 것입니다. 이것은 확실히 작업을 완료하지만 각 릴리스에서 참조를 업데이트하는 것은 번거로울 수 있습니다.

우리가이 문제를 처음으로 다루는 사람이 아니라고 확신하기 때문에 커뮤니티에 버릴 것이라고 생각했습니다. 코드를 업데이트 할 때 클라이언트가 캐시를 업데이트하도록 어떻게 보장합니까? 위에서 설명한 방법을 사용하는 경우 변경을 단순화하는 프로세스를 사용하고 있습니까?


내가 아는 한 일반적인 해결책은 ?<version>스크립트의 src 링크에 를 추가하는 것입니다.

예를 들면 :

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

이 시점에서 모든 스크립트 태그에서 이러한 "버전 번호"를 증가시키는 찾기-바꾸기보다 더 좋은 방법이 없다고 가정합니다.

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

다음과 같이 보일 것입니다.

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

물론, 언제나처럼 더 나은 솔루션이 있습니다 이것 .


현재 시간을 URL에 추가하는 것은 실제로 일반적인 해결책입니다. 그러나 원하는 경우 웹 서버 수준에서이를 관리 할 수도 있습니다. 자바 스크립트 파일에 대해 다른 HTTP 헤더를 보내도록 서버를 구성 할 수 있습니다.

예를 들어, 파일이 1 일 이하로 캐시되도록하려면 다음을 전송합니다.

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

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

Cache-Control: no-cache, must-revalidate

Google Page-Speed ​​: 정적 리소스의 URL에 검색어 문자열을 포함하지 마세요. 대부분의 프록시, 특히 버전 3.0까지 Squid는 "?"가있는 리소스를 캐시하지 않습니다. Cache-control : public 헤더가 응답에있는 경우에도 URL에 있습니다. 이러한 리소스에 대해 프록시 캐싱을 사용하려면 정적 리소스에 대한 참조에서 쿼리 문자열을 제거하고 대신 매개 변수를 파일 이름 자체로 인코딩합니다.

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


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

이 답변은 6 년 늦었지만 많은 곳에서이 답변을 볼 수 없습니다. HTML5는 이 문제를 해결하는 데 사용되는 Application Cache도입했습니다 . 내가 작성한 새 서버 코드가 사람들의 브라우저에 저장된 오래된 자바 스크립트를 충돌시키는 것을 발견했기 때문에 자바 스크립트를 만료하는 방법을 찾고 싶었습니다. 다음과 같은 매니페스트 파일을 사용하십시오.

CACHE MANIFEST
# Aug 14, 2014
/mycode.js

NETWORK:
*

사용자가 캐시를 업데이트하기를 원할 때마다 새 타임 스탬프로이 파일을 생성합니다. 참고로 이것을 추가 하면 매니페스트가 지시 할 때까지 브라우저가 다시로드 되지 않습니다 (사용자가 페이지를 새로 고침하더라도).


파일 크기를로드 매개 변수로 추가하는 것은 어떻습니까?

<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아파치에서 (내 생각에) have stuff_*.js가려고stuff.js


ASP.NET 페이지의 경우 다음을 사용하고 있습니다.

전에

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

후 (강제 재 장전)

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

DateTime.Now.Ticks 추가는 매우 잘 작동합니다.


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();
    }
    ...
}

If you're generating the page that links to the JS files a simple solution is appending the file's last modification timestamp to the generated links.

This is very similar to Huppie's answer, but works in version control systems without keyword substitution. It's also better than append the current time, since that would prevent caching even when the file didn't change at all.


The jQuery function getScript can also be used to ensure that a js file is indeed loaded every time the page is loaded.

This is how I did it:

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

Check the function at http://api.jquery.com/jQuery.getScript/

By default, $.getScript() sets the cache setting to false. This appends a timestamped query parameter to the request URL to ensure that the browser downloads the script each time it is requested.


We have been creating a SaaS for users and providing them a script to attach in their website page, and it was not possible to attach a version with the script as user will attach the script to their website for functionalities and i can't force them to change the version each time we update the script

So, we found a way to load the newer version of the script each time user calls the original script

the script link provided to user

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

the script file

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
}

Explanation:

The user have attached the script provided to them in their website and we checked for the unique token attached with the script exists or not using jQuery selector and if not then load it dynamically with newer token (or version)

This is call the same script twice which could be a performance issue, but it really solves the problem of forcing the script to not load from the cache without putting the version in the actual script link given to the user or client

Disclaimer: Do not use if performance is a big issue in your case.


The common practice nowadays is to generate a content hash code as part of the file name to force the browser especially IE to reload the javascript files or css files.

For example,

vendor.a7561fb0e9a071baadb9.js
main.b746e3eb72875af2caa9.js

It is generally the job for the build tools such as webpack. Here is more details if anyone wants to try out if you are using webpack.


One solution is to append a query string with a timestamp in it to the URL when fetching the resource. This takes advantage of the fact that a browser will not cache resources fetched from URLs with query strings in them.

You probably don't want the browser not to cache these resources at all though; it's more likely that you want them cached, but you want the browser to fetch a new version of the file when it is made available.

The most common solution seems to be to embed a timestamp or revision number in the file name itself. This is a little more work, because your code needs to be modified to request the correct files, but it means that, e.g. version 7 of your snazzy_javascript_file.js (i.e. snazzy_javascript_file_7.js) is cached on the browser until you release version 8, and then your code changes to fetch snazzy_javascript_file_8.js instead.


Use a version GET variable to prevent browser caching.

Appending ?v=AUTO_INCREMENT_VERSION to the end of your url prevents browser caching - avoiding any and all cached scripts.


My colleague just found a reference to that method right after I posted (in reference to css) at http://www.stefanhayden.com/blog/2006/04/03/css-caching-hack/. Good to see that others are using it and it seems to work. I assume at this point that there isn't a better way than find-replace to increment these "version numbers" in all of the script tags?


Athough it is framework specific, Django 1.4 has this functionailty which works in a similar fashion to the link to the 'greenfelt' site in the above answer


In PHP:

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

In HTML:

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

How it works:

In HTML, write the filepath and name as you wold do, but in the function only. PHP gets the filetime of the file and returns the filepath+name+"?"+time of latest change


Cache Busting in ASP.NET Core via a tag helper will handle this for you and allow your browser to keep cached scripts/css until the file changes. Simply add the tag helper asp-append-version="true" to your script (js) or link (css) tag:

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

Dave Paquette has a good example and explanation of cache busting here (bottom of page) Cache Busting


In asp.net mvc you can use @DateTime.UtcNow.ToString() for js file version number. Version number auto change with date and you force clients browser to refresh automatically js file. I using this method and this is work well.

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

Simplest solution? Don't let the browser cache at all. Append the current time (in ms) as a query.

(You are still in beta, so you could make a reasonable case for not optimizing for performance. But YMMV here.)


The advantage of using a file.js?V=1 over a fileV1.js is that you do not need to store multiple versions of the JavaScript files on the server.

The trouble I see with file.js?V=1 is that you may have dependant code in another JavaScript file that breaks when using the new version of the library utilities.

For the sake of backwards compatibility, I think it is much better to use jQuery.1.3.js for your new pages and let existing pages use jQuery.1.1.js, until you are ready to upgrade the older pages, if necessary.


One simple way. Edit 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]

Below worked for me:

<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>

location.reload(true);

참조 https://www.w3schools.com/jsref/met_loc_reload.asp를

이 문제를 피하기 위해 브라우저의 캐시 대신 웹 서버에서 자바 스크립트를 다시 검색하도록하기 위해이 코드 줄을 동적으로 호출합니다.

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

반응형