ฉันจะบังคับให้ลูกค้ารีเฟรชไฟล์ JavaScript ได้อย่างไร


595

ขณะนี้เรากำลังทำงานในรุ่นเบต้าส่วนตัวและยังอยู่ในขั้นตอนของการเปลี่ยนแปลงอย่างรวดเร็วแม้ว่าจะเห็นได้ชัดว่าเมื่อการใช้งานเริ่มเพิ่มขึ้นเราจะทำให้กระบวนการนี้ช้าลง สิ่งหนึ่งที่เรากำลังประสบอยู่คือหลังจากที่เราผลักดันการอัปเดตด้วยไฟล์ JavaScript ใหม่เบราว์เซอร์ไคลเอ็นต์ยังคงใช้ไฟล์แคชเวอร์ชันและพวกเขาไม่เห็นการอัปเดต เห็นได้ชัดว่าในการโทรสนับสนุนเราสามารถแจ้งให้พวกเขาทำการctrlF5รีเฟรชเพื่อให้แน่ใจว่าพวกเขาได้รับไฟล์ที่ทันสมัยจากเซิร์ฟเวอร์ แต่มันจะดีกว่าที่จะจัดการกับมันก่อนเวลานั้น

ความคิดปัจจุบันของเราคือการแนบหมายเลขเวอร์ชั่นลงในชื่อของไฟล์ JavaScript จากนั้นเมื่อทำการเปลี่ยนแปลงให้เพิ่มเวอร์ชันในสคริปต์และอัปเดตข้อมูลอ้างอิงทั้งหมด สิ่งนี้ทำให้งานเสร็จสมบูรณ์ แต่การอัปเดตข้อมูลอ้างอิงในแต่ละรุ่นอาจทำให้ยุ่งยาก

เนื่องจากฉันแน่ใจว่าเราไม่ใช่คนแรกที่จัดการเรื่องนี้ฉันคิดว่าฉันจะโยนมันออกไปสู่ชุมชน คุณมั่นใจได้อย่างไรว่าลูกค้าอัปเดตแคชของพวกเขาเมื่อคุณอัปเดตรหัสของคุณ? หากคุณใช้วิธีที่อธิบายไว้ข้างต้นคุณใช้กระบวนการที่ทำให้การเปลี่ยนแปลงง่ายขึ้นหรือไม่


คำตอบ:


529

เท่าที่ฉันรู้วิธีแก้ไขปัญหาทั่วไปคือการเพิ่ม?<version>ลิงก์ src ของสคริปต์

ตัวอย่างเช่น

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

ฉันคิดว่า ณ จุดนี้มีวิธีที่ดีกว่า find-replace เพื่อเพิ่ม "หมายเลขรุ่น" เหล่านี้ในแท็กสคริปต์ทั้งหมดหรือไม่

คุณอาจมีระบบควบคุมเวอร์ชันทำเพื่อคุณหรือไม่? ระบบควบคุมเวอร์ชันส่วนใหญ่มีวิธีการฉีดหมายเลขการตรวจทานแก้ไขอัตโนมัติเมื่อทำการเช็คอิน

มันจะมีลักษณะเช่นนี้:

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

แน่นอนว่ามีวิธีแก้ปัญหาที่ดีกว่าเช่นนี้เสมอ


5
ไม่มีใครรู้ว่า IE7 ละเว้นนี้หรือไม่? ดูเหมือนว่าจะไม่สนใจข้อมูลต่อท้ายและใช้ไฟล์แคชเมื่อฉันทดสอบในมุมมองการเปรียบเทียบ IE8
Shane Reustle

4
ฉันรู้เสมอว่าสตริงการสืบค้นเป็นคู่ของคีย์ - ค่าเหมือนกับใน? ver = 123 ขอบคุณ! :)
Ankur-m

6
ฉันคิดว่ามันไม่ได้เกี่ยวกับหมายเลขรุ่นที่สูงขึ้นหรือต่ำลง แต่เกี่ยวกับการเปลี่ยนค่าตัวแปรที่ผนวกรวมเป็นสิ่งที่เบราว์เซอร์ยังไม่ได้แคช
Max Girkens

2
เมื่อเร็ว ๆ นี้เราพบปัญหาเดียวกันและสิ่งที่ดีที่สุดที่ฉันจะได้รับคือฟังก์ชั่นง่าย ๆ ที่แนบมา "? mod = 123456" โดยที่ 123456 คือการประทับเวลาแบบ unix ของวันที่แก้ไขในไฟล์ ที่ดูเหมือนว่าจะแก้ไขปัญหาในขณะที่ยังคงให้การแคชตามความเหมาะสม อย่างไรก็ตามฉันยังคงเห็นเบราว์เซอร์ที่ไม่สนใจคำสั่งนี้และใช้ JS ตัวเก่าอยู่ดี แต่ฉันไม่ทราบว่ามี "การแก้ไขแบบสมบูรณ์" ที่สวยงาม
VPel

31
เพื่อความตระหนัก: นี่ถือเป็นแฮ็ค เมธอดนี้หลอกให้เบราว์เซอร์คิดว่ามีการระบุไฟล์ใหม่เนื่องจากมันจะดูที่ชื่อไฟล์แบบเต็มโดยไม่ต้องตีความมัน foo.js?1ไม่ใช่ชื่อเดียวกันfoo.js?2ดังนั้นเบราว์เซอร์จะคิดว่าพวกเขาเป็นสองไฟล์ที่แตกต่างกัน ข้อเสียอย่างหนึ่งคือไฟล์ทั้งสองนั้นจะมีอยู่ในแคชของผู้ใช้พร้อมกันโดยใช้พื้นที่ไม่จำเป็น
Lee White

88

การต่อเวลาปัจจุบันไปยัง URL นั้นเป็นวิธีแก้ไขปัญหาทั่วไป อย่างไรก็ตามคุณสามารถจัดการสิ่งนี้ได้ในระดับเว็บเซิร์ฟเวอร์หากคุณต้องการ เซิร์ฟเวอร์สามารถกำหนดค่าให้ส่งส่วนหัว HTTP ที่แตกต่างกันสำหรับไฟล์จาวาสคริปต์

ตัวอย่างเช่นหากต้องการบังคับให้แคชไฟล์ไม่เกิน 1 วันคุณจะต้องส่ง:

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

สำหรับรุ่นเบต้าหากคุณต้องการบังคับให้ผู้ใช้รับข้อมูลล่าสุดเสมอคุณจะใช้:

Cache-Control: no-cache, must-revalidate

3
คุณกรุณาเจาะจงมากขึ้นได้ไหม
Kreker

6
เขากำลังพูดถึงส่วนหัวที่ส่งโดยเว็บเซิร์ฟเวอร์สำหรับแต่ละไฟล์ ควรกำหนดค่าได้ใน Apache เช่น ฉันคิดว่านี่จะเป็นวิธีที่ดีที่สุด
Pierre de LESPINAY

1
คุณจะกำหนดค่านี้ที่ไหน
Diego

2
สำหรับ webapp พัฒนาอาจเป็นทางออกที่ดี สำหรับไซต์ที่ใช้งานจริงซึ่งคุณไม่ต้องการทำให้แคชใช้ไม่ได้ตลอดไปนั่นไม่ใช่วิธีแก้ปัญหาที่ดีเว้นแต่คุณจะรู้ว่าเบราว์เซอร์ไคลเอนต์เป้าหมายแต่ละตัวนั้นมาที่ไซต์นั้น มันทำให้ฉันคิดถึงคุณสมบัติของเว็บเซิร์ฟเวอร์: ปรับพารามิเตอร์อายุสูงสุดตามวันที่ปรับใช้ที่กำหนดไว้ นั่นจะน่ากลัว
Claude Brisson

Chrome ต้องการการตั้งค่าเหล่านี้เพื่อแคชอย่างเหมาะสม หากไม่มีพวกเขา Chrome จะทำการแคชไฟล์อย่างถาวร Mozilla ใช้ค่าเริ่มต้นที่สมเหตุสมผลมากขึ้น ดูเพิ่มเติมได้ที่: agiletribe.wordpress.com/2018/01/29/caching-for-chrome
AgilePro

42

Google Page-Speed: ไม่รวมสตริงการสืบค้นใน URL สำหรับทรัพยากรคงที่ พร็อกซีส่วนใหญ่โดยเฉพาะอย่างยิ่ง Squid up ถึงเวอร์ชัน 3.0 ไม่แคชทรัพยากรด้วย "?" ใน URL แม้ว่า Cache-control: public header จะมีอยู่ในการตอบกลับ หากต้องการเปิดใช้งานการแคชพร็อกซีสำหรับทรัพยากรเหล่านี้ให้ลบสตริงข้อความค้นหาออกจากการอ้างอิงไปยังทรัพยากรแบบคงที่และเข้ารหัสพารามิเตอร์ลงในชื่อไฟล์ด้วยตนเอง

ในกรณีนี้คุณสามารถรวมรุ่นใน URL อดีต: http://abc.com/ v1.2 /script.js และใช้ mod_rewrite Apache เพื่อเปลี่ยนเส้นทางการเชื่อมโยงไปhttp://abc.com/script.js เมื่อคุณเปลี่ยนเวอร์ชันเบราว์เซอร์ไคลเอ็นต์จะอัปเดตไฟล์ใหม่


ฉันลอง วิธีการแก้ปัญหาและใน IE8 และฉันได้รับข้อผิดพลาดจาวาสคริปต์ Mod rewrite เป็นตัวเลือก แต่ในกรณีส่วนใหญ่เราไม่สามารถควบคุมเซิร์ฟเวอร์ได้ ฉันชอบท้ายรุ่นในไฟล์ js ตัวเองหรือมีโฟลเดอร์สำหรับแต่ละรุ่น
คาร์ทิค Sankar

@ HắcHuyền Minh: แต่เมื่อสคริปต์จะโหลดใหม่ก็ไม่ควรโหลดจาก proxy-cache ...
Stefan Steiger

34

การใช้งานนี้ถูกตัดทอน: 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:
*

และสร้างไฟล์นี้ด้วยการประทับเวลาใหม่ทุกครั้งที่คุณต้องการให้ผู้ใช้อัพเดตแคช หากคุณเพิ่มสิ่งนี้เบราว์เซอร์จะไม่โหลดซ้ำ (แม้ว่าผู้ใช้จะรีเฟรชหน้าเพจ) จนกว่ารายการจะแจ้งให้ทราบ


การแก้ปัญหานี้เป็นสิ่งที่ดีจริงๆตราบเท่าที่คุณจำการปรับปรุงแฟ้มประจักษ์ :)
Mattis

24
โปรดอ่านเอกสารประกอบเนื่องจากคุณสมบัตินี้ได้ถูกลบออกจากเว็บมาตรฐานdeveloper.mozilla.org/en-US/docs/Web/HTML/…
Flavia Obreja

1
FWIW ฉันลงเอยด้วยการไม่ใช้โซลูชันนี้ มันง่ายกว่ามากในการใช้ / รักษา?<version> แนวทาง
amos

28

วิธีเพิ่มขนาดไฟล์เป็นพารามิเตอร์โหลด

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

ดังนั้นทุกครั้งที่คุณอัปเดตไฟล์การเปลี่ยนแปลงพารามิเตอร์ "filever"

เมื่อคุณอัปเดตไฟล์และผลลัพธ์การอัปเดตของคุณมีขนาดเท่ากัน อัตราต่อรองคืออะไร?


4
สิ่งนี้ใช้แท็ก PHP และถ้าใช้ PHP ก็เป็นความคิดที่ดี
Jerther

1
ผมคิดว่าการเพิ่ม CHANGEDATE จะดีกว่าขนาดไฟล์ :)
Mazz

2
ความคิดเริ่มต้นของฉันคือการเพิ่มแฮชของไฟล์แทนที่จะเป็นเวอร์ชัน
Mike Cheel

ฉันคิดว่ามันใช้งานได้ถ้าเพิ่มการประทับเวลา Unix ใช่ไหม? เช่น '... file.js? filever = <? = time ()?>
garanda

3
ใช้ filemtime ($ file) มันจะแสดงผลการประทับเวลาของไฟล์พร้อม time () คุณไม่สามารถใช้แคชได้เพราะมันเปลี่ยนทุกวินาที
neoteknic

19

ไม่ใช่ไฟล์แคชของเบราว์เซอร์ที่มี'?' ในนั้น. สิ่งที่ฉันทำเพื่อให้แน่ใจว่าแคชมากที่สุดเท่าที่เป็นไปได้ฉันรวมเวอร์ชันไว้ในชื่อไฟล์

ดังนั้นแทนที่จะstuff.js?123ทำstuff_123.js

ฉันใช้mod_redirect(ฉันคิดว่า) ใน apache เพื่อที่have stuff_*.jsจะไปstuff.js


คุณช่วยอธิบายเกี่ยวกับสิ่งที่คุณทำใน. htaccess ด้วย mod_redirect ได้ไหม?
Venkat D.

3
คำอธิบายรายละเอียดของวิธีการนี้สามารถพบได้ที่particletree.com/notebook/...
คาร์ล Bartel

3
มันจะดีถ้าคุณสามารถใส่.htaccessรหัสของคุณในคำตอบสำหรับการอ้างอิงในอนาคต
Fizzix

1
เบราว์เซอร์ใดที่ไม่มีแคชไฟล์ด้วย "?" ในนั้น?
rosell.dk

13

สำหรับหน้า 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 ทำงานได้ดีมาก


31
สิ่งนี้ขัดกับกลไกการแคชทั้งหมดในฝั่งไคลเอ็นต์ ควรแทนที่พารามิเตอร์ดัมมีบางอย่างเช่น "{เวอร์ชันหลัก} _ {minor_version} _ {build_number} _ {Revision} ซึ่งจะไม่ซ้ำกันสำหรับแต่ละรุ่น
Tohid

14
แม้ว่านี่อาจเป็นทางออกของพระเจ้าในสภาพแวดล้อมการพัฒนา แต่ก็ไม่เหมาะสำหรับการผลิต นี่จะเป็นการปิดการใช้งานแคชในแต่ละครั้งที่โหลดหน้าไฟล์ ลองจินตนาการถึงการโหลดหน้าเว็บขนาด 10k ต่อวันด้วยไฟล์ขนาด 50Kb หนึ่งไฟล์ซึ่งหมายถึงไฟล์ Javascript 500Mb ทุกวัน
PhilDulac

@PhilDulac คุณสามารถเปลี่ยนจาก Ticks เพื่อส่งคืนค่าสตริงของวันเช่นหรือเดือนหรือสัปดาห์ของเดือน ในที่สุดมันก็แสดงให้คุณเห็นว่าจะใช้วิธี? v ได้อย่างไร
alex

3
@alex แน่นอน ฉันแค่อยากจะเตือนว่าหากการใช้งานที่แสดงในคำตอบทำให้เกิดการผลิตมันอาจมีผลกระทบที่ไม่แสดงในการพัฒนา
PhilDulac

2
วิธีที่เป็นไปได้เพื่อให้แน่ใจว่าสำเนาใหม่ได้รับการโหลดหนึ่งครั้งทุกวันอาจจะใช้ '<script src = "/ สคริปต์ / หน้า / common.js? ver <% = DateTime.Now.ToString (" yyyyMMdd ")%>" ชนิด = "text / javascript ของ"> </ script>' ดังนั้นจึงโหลดหนึ่งครั้งในตอนต้นของวันจากนั้นแคช
Robb Sadler

7

สำหรับ 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();
    }
    ...
}

ฉันกำลังใช้. Ticks (ดูคำตอบของฉันในหน้านี้)
Ravi Ram

5

แนวปฏิบัติทั่วไปในปัจจุบันคือการสร้างรหัสแฮชเนื้อหาเป็นส่วนหนึ่งของชื่อไฟล์เพื่อบังคับเบราว์เซอร์โดยเฉพาะ IE เพื่อโหลดไฟล์ javascript หรือ css

ตัวอย่างเช่น,

ผู้ขาย a7561fb0e9a071baadb9 .js
main b746e3eb72875af2caa9 .js

โดยทั่วไปแล้วจะเป็นงานสำหรับเครื่องมือสร้างเช่น webpack นี่คือรายละเอียดเพิ่มเติมหากใครต้องการลองใช้ถ้าคุณใช้ webpack


4

หากคุณกำลังสร้างเพจที่เชื่อมโยงไปยังไฟล์ JS ทางออกที่ง่ายคือการผนวกเวลาประทับการแก้ไขครั้งล่าสุดของไฟล์ไปยังลิงก์ที่สร้างขึ้น

นี่คล้ายกับคำตอบของ Huppie แต่ทำงานในระบบควบคุมเวอร์ชันที่ไม่มีการทดแทนคำหลัก นอกจากนี้ยังดีกว่าผนวกเวลาปัจจุบันเนื่องจากจะป้องกันการแคชแม้ว่าไฟล์จะไม่เปลี่ยนแปลงเลย


ฉันชอบโซลูชันนี้เนื่องจากง่ายต่อการดูแลรักษา หากคุณอัปเดตไฟล์. js นั่นคือทั้งหมดที่คุณต้องทำ ไม่จำเป็นต้องอัปเดตการอ้างอิงใด ๆ กับไฟล์ด้วยเนื่องจากรหัสของคุณจะเพิ่มการประทับเวลาที่ปรับปรุงล่าสุดโดยอัตโนมัติ
NL3294

3

สามารถใช้ฟังก์ชัน jQuery getScript เพื่อให้แน่ใจว่าโหลดไฟล์ js ทุกครั้งที่โหลดหน้าเว็บ

นี่คือวิธีที่ฉันทำ:

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

ตรวจสอบฟังก์ชั่นที่http://api.jquery.com/jQuery.getScript/

โดยค่าเริ่มต้น $ .getScript () ตั้งค่าแคชเป็นเท็จ สิ่งนี้จะผนวกพารามิเตอร์การสืบค้นที่ประทับเวลาเข้ากับ URL ที่ร้องขอเพื่อให้แน่ใจว่าเบราว์เซอร์จะดาวน์โหลดสคริปต์ทุกครั้งที่มีการร้องขอ


8
เราจำเป็นต้องแคชไฟล์หากไม่มีการเปลี่ยนแปลงเกิดขึ้น
Leo Lee

3

ใน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 เขียนfilepathและชื่อตามที่คุณทำ แต่ในฟังก์ชั่นเท่านั้น PHP ได้รับfiletimeไฟล์และคืนค่าการfilepath+name+"?"+timeเปลี่ยนแปลงล่าสุด


3

เราได้สร้าง 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

ใน asp.net mvc คุณสามารถใช้@ DateTime.UtcNow.ToString ()สำหรับหมายเลขเวอร์ชันของไฟล์ js หมายเลขเวอร์ชันเปลี่ยนแปลงอัตโนมัติพร้อมวันที่และคุณบังคับให้เบราว์เซอร์ไคลเอ็นต์รีเฟรชไฟล์ js โดยอัตโนมัติ ฉันใช้วิธีนี้และใช้งานได้ดี

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

เช่นเดียวกับวิธีแก้ไขปัญหาอื่น ๆ ที่แนะนำซึ่งจะทำให้ไฟล์ไม่ถูกแคชซึ่งโดยทั่วไปมักไม่พึงปรารถนา ตราบใดที่ไม่มีการเปลี่ยนแปลงไฟล์คุณอาจต้องการให้ไคลเอ็นต์ใช้เวอร์ชันแคชแทนการดาวน์โหลดไฟล์ที่ไม่เปลี่ยนแปลงอีกครั้งทุกครั้ง
Philip Stratford

คุณสามารถใช้รหัสด้านล่างด้วยเหตุผลของคุณไฟล์แคชพร้อมหมายเลขเวอร์ชัน <script src = "~/JsFilePath/JsFile.js?v=@GetAppVersionNumber ()"> </script>
dragonal

2

location.reload (จริง);

ดูhttps://www.w3schools.com/jsref/met_loc_reload.asp

ฉันเรียกรหัสบรรทัดนี้แบบไดนามิกเพื่อให้แน่ใจว่าจาวาสคริปต์ถูกเรียกคืนจากเว็บเซิร์ฟเวอร์แทนแคชของเบราว์เซอร์เพื่อหลีกเลี่ยงปัญหานี้


การเพิ่มลงonload="location.reload();"ในแบบฟอร์มของฉันทำให้ฉันได้รับ JS ใหม่หลังจากรีเฟรชแทนการเปิดหน้าเว็บของฉันใหม่ นี่เป็นทางออกที่สง่างามยิ่งกว่า ขอบคุณ!
ZX9

ขอบคุณสามารถใช้สิ่งนี้พร้อมตรวจสอบว่ามีการรับรู้ IP แต่ไม่ได้ใช้ในการเข้าสู่ระบบเนื่องจากการอัปเดตครั้งล่าสุดดำเนินการนี้ในหน้าดัชนีหลังจากผู้ใช้เข้าสู่ระบบครั้งแรก
Fi Horan

onload = "location.reload (จริง);" ข้างต้นไม่ทำงานสำหรับฉัน (ใช้กระติกน้ำและ Chrome รุ่นปัจจุบัน) ด้วย: w3schools.com/jsref/met_loc_reload.asp
aspiringGuru

1

ทางออกหนึ่งคือการผนวกสตริงแบบสอบถามที่มีการประทับเวลาในนั้นไปยัง URL เมื่อดึงทรัพยากร สิ่งนี้ใช้ประโยชน์จากข้อเท็จจริงที่ว่าเบราว์เซอร์จะไม่แคชทรัพยากรที่ดึงมาจาก URL ด้วยสตริงการสืบค้นในนั้น

คุณอาจไม่ต้องการให้เบราว์เซอร์ไม่แคชทรัพยากรเหล่านี้เลย มีโอกาสมากขึ้นที่คุณต้องการแคชไว้ แต่คุณต้องการให้เบราว์เซอร์ดึงไฟล์เวอร์ชันใหม่เมื่อมีให้ใช้งาน

วิธีแก้ปัญหาที่พบบ่อยที่สุดน่าจะเป็นการฝังเวลาหรือหมายเลขการแก้ไขในชื่อไฟล์เอง นี่เป็นการทำงานอีกเล็กน้อยเนื่องจากรหัสของคุณต้องได้รับการแก้ไขเพื่อขอไฟล์ที่ถูกต้อง แต่หมายความว่าเช่นเวอร์ชัน 7 ของคุณsnazzy_javascript_file.js(เช่นsnazzy_javascript_file_7.js) ถูกแคชไว้ในเบราว์เซอร์จนกว่าคุณจะปล่อยรุ่น 8 แล้วเปลี่ยนรหัสของคุณเป็น ดึงข้อมูลsnazzy_javascript_file_8.jsแทน


1

ข้อดีของการใช้งานแบบfile.js?V=1over a fileV1.jsคือคุณไม่จำเป็นต้องจัดเก็บไฟล์ JavaScript หลายเวอร์ชันไว้บนเซิร์ฟเวอร์

ปัญหาที่ฉันเห็นfile.js?V=1คือคุณอาจมีโค้ดที่ต้องพึ่งพาในไฟล์ JavaScript อื่นที่แตกเมื่อใช้เวอร์ชันใหม่ของยูทิลิตี้ไลบรารี

เพื่อความเข้ากันได้แบบย้อนหลังฉันคิดว่ามันดีกว่าที่จะใช้jQuery.1.3.jsสำหรับหน้าใหม่ของคุณและให้หน้าเว็บที่มีอยู่ใช้jQuery.1.1.jsจนกว่าคุณจะพร้อมอัปเกรดหน้าเก่าหากจำเป็น


1

ใช้GETตัวแปรversion เพื่อป้องกันการแคชของเบราว์เซอร์

ผนวก?v=AUTO_INCREMENT_VERSIONกับจุดสิ้นสุดของแคช URL ป้องกันเบราว์เซอร์ของคุณ - หลีกเลี่ยงสคริปต์ใด ๆ และทั้งหมดที่เก็บไว้ชั่วคราว


1

เพื่อนร่วมงานของฉันเพิ่งพบการอ้างอิงถึงวิธีการว่าหลังจากที่ผมโพสต์ (ในการอ้างอิงถึง CSS) ที่http://www.stefanhayden.com/blog/2006/04/03/css-caching-hack/ ดีที่เห็นว่าคนอื่นใช้มันและดูเหมือนว่าจะทำงาน ฉันคิดว่า ณ จุดนี้มีวิธีที่ดีกว่า find-replace เพื่อเพิ่ม "หมายเลขรุ่น" เหล่านี้ในแท็กสคริปต์ทั้งหมดหรือไม่



1

Cache Busting ใน ASP.NET Core ผ่านตัวช่วยแท็กจะจัดการสิ่งนี้ให้คุณและอนุญาตให้เบราว์เซอร์ของคุณเก็บสคริปต์ / css ที่แคชไว้จนกว่าไฟล์จะเปลี่ยน เพียงเพิ่มเครื่องมือช่วยเหลือแท็ก asp-append-version = "true" ลงในสคริปต์ (js) หรือแท็กลิงก์ (css) ของคุณ:

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

Dave Paquette มีตัวอย่างที่ดีและคำอธิบายของการใช้แคชที่นี่ (ด้านล่างของหน้า) การป้องกันแคช


สิ่งนี้ไม่ทำงานใน ASP.NET ปกติหรือไม่ ฉันพยายามเพิ่ม asp-append-version ลงในแท็กสคริปต์ของฉันและเบราว์เซอร์ทั้งหมดเห็นเป็นแท็กสคริปต์ตรงตามที่ปรากฏในแหล่งที่มารวมถึงแอตทริบิวต์ asp-append-version
tolsen64

นี่คือแอตทริบิวต์. NET Core ที่เกี่ยวข้องกับ Tag Helpers มันต่อท้ายชื่อสคริปต์ด้วยเวอร์ชันเพื่อให้เซิร์ฟเวอร์ / เบราว์เซอร์เห็นเวอร์ชั่นล่าสุดและดาวน์โหลด
เสมอ

0

ทางออกที่ง่ายที่สุด? อย่าให้แคชเบราว์เซอร์เลย ผนวกเวลาปัจจุบัน (เป็น ms) เป็นแบบสอบถาม

(คุณยังอยู่ในช่วงเบต้าดังนั้นคุณสามารถสร้างกรณีที่เหมาะสมสำหรับการไม่ปรับประสิทธิภาพให้เหมาะสม แต่ YMMV ที่นี่)


13
IMHO นี่เป็นทางออกที่ไม่ดี ถ้าคุณไม่ได้อยู่ใน BETA และคุณผลักดันการอัปเดตที่สำคัญ
d -_- b

0

วิธีการง่ายๆ แก้ไข 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]

สิ่งนี้ทำให้เกิดการเปลี่ยนเส้นทางซึ่งเป็นวิธีแก้ปัญหาที่ไม่ได้ผล
doublejr

0

ทำงานด้านล่างสำหรับฉัน:

<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>
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.