ล้างแคชใน JavaScript


179

ฉันจะล้างแคชของเบราว์เซอร์ด้วย JavaScript ได้อย่างไร

เราปรับใช้รหัส JavaScript ล่าสุด แต่เราไม่สามารถรับรหัส JavaScript ล่าสุดได้

บทบรรณาธิการ: คำถามนี้มีการทำซ้ำกึ่งในสถานที่ต่อไปนี้และคำตอบในคำถามแรกของคำถามต่อไปนี้น่าจะดีที่สุด คำตอบที่ได้รับการยอมรับนี้ไม่ใช่ทางออกที่ดีที่สุดอีกต่อไป

วิธีบังคับให้เบราว์เซอร์โหลดไฟล์ CSS / JS ที่แคชใหม่

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

โหลดข้อมูล Javascript ต้นฉบับ / json โลคัลแบบไดนามิกอีกครั้ง


5
สิ่งนี้ทำให้ฉันสับสน: "เราใช้รหัสจาวาสคริปต์ล่าสุด แต่เราไม่สามารถรับรหัสจาวาสคริปต์ล่าสุดได้"
อินสแตนซ์ของฉัน

14
ฉันคิดว่าคุณหมายถึงวิธีการบังคับเบราว์เซอร์ไคลเอ็นต์ให้ใช้จาวาสคริปต์เวอร์ชันล่าสุดไม่ใช่เวอร์ชันแคชในกรณีนี้คุณต้องได้รับคำตอบจาก Greg หากคุณต้องการทราบวิธีการทำในเบราว์เซอร์ของคุณเองมันเป็นคำตอบของ David Johnstone
Benjol


4
วิธีการทั่วไปคือการแนบ?version=xxxไฟล์ที่เชื่อมโยงกับ JS ของคุณผ่านขั้นตอนการสร้าง การสร้างใหม่ทุกครั้งจะขอไฟล์ JS เวอร์ชันใหม่
Juan Mendes

1
@JuanMendes สิ่งนี้ไม่ได้ผลเสมอไป แนะนำขั้นตอนเดียวกันนี้เมื่อผู้คนมีปัญหาในการพยายามดู favicon ล่าสุด มันไม่รับประกันว่าจะทำงาน
uSeRnAmEhAhAhAhAhA

คำตอบ:


202

คุณสามารถเรียกwindow.location.reload (จริง)เพื่อโหลดหน้าปัจจุบัน มันจะไม่สนใจรายการแคชใด ๆ และดึงสำเนาใหม่ของหน้า, CSS, รูปภาพ, JavaScript, ฯลฯ จากเซิร์ฟเวอร์ สิ่งนี้ไม่ได้ล้างแคชทั้งหมด แต่มีผลในการล้างแคชสำหรับหน้าเว็บที่คุณเปิดอยู่

อย่างไรก็ตามกลยุทธ์ที่ดีที่สุดของคุณคือการสร้างเวอร์ชั่นพา ธ หรือชื่อไฟล์ตามที่ระบุไว้ในคำตอบอื่น ๆ นอกจากนี้โปรดดูการแก้ไขชื่อไฟล์: อย่าใช้การสอบถามด้วยเหตุผลไม่ควรใช้?v=nเป็นโครงร่างการกำหนดรุ่นของคุณ


6
ว้าวขอบคุณ! สิ่งนี้ทำงานได้ดีสำหรับแคชของแอปพลิเคชัน HTML5 ที่โหลดจากไฟล์ cache.manifest เช่นกัน ฉันมีรายการเก่าที่ไม่ได้ถูกลบออกจากหน่วยความจำดังนั้นเบราว์เซอร์เดียวที่มีแคชก็จะไม่แสดงไฟล์ใหม่ ฉันพิมพ์สิ่งนี้ในคอนโซล javascript และทำงานได้ดี ขอบคุณ!
JayCrossler

2
แต่ revving โดยการเปลี่ยนชื่อไฟล์ ... คุณจะไม่เก็บเวอร์ชันก่อนหน้าทั้งหมดไว้ใช่ไหม? ไม่เช่นนั้นคุณจะได้รับความพยายามที่ล้มเหลวจำนวนมากจากเครื่องมือค้นหาและสิ่งที่ไม่ควรอ่านรุ่นเก่า (หรือภาพบุ๊คมาร์ค / เชื่อมโยง)
Rodolfo

1
เป็นอย่างไรบ้างที่ฉันไม่ได้คิดอย่างนั้นโอเคคุณ
osdamv

1
เหมือนกับผู้ใช้คลิกที่ปุ่มรีเฟรช?
GMsoF

2
@Manuel มันจะปิดการเข้าถึงหน้าเว็บจากแคชของ url ที่แน่นอนที่คุณเรียกว่า location.reload (true) เท่านั้น มันจะไม่ลบหน้าต้นฉบับจากแคชเพียงแค่ต่อท้ายการประทับเวลากับคำขอใหม่และหากมีการโทรอื่น ๆ แบบอะซิงโครนัสโดยหน้านี้คำขอเหล่านั้นจะไม่ปิดใช้งานการแคช เช่น. หากคุณรีเฟรชหน้าเว็บด้วยการโหลดซ้ำ (จริง) ที่โหลด html บางส่วนและหน้านั้นมีสคริปต์ที่ทำให้ ajax เรียกอีกครั้งเพื่อให้ html เพิ่มเติมแสดงบนหน้าเดียวกันคำขอที่สองจะไม่ปิดใช้งานการแคช
J. Schei

114

คุณไม่สามารถล้างแคชด้วย javascript วิธีทั่วไปคือการผนวกหมายเลขการแก้ไขหรือการประทับเวลาที่ปรับปรุงล่าสุดไปยังไฟล์เช่นนี้

myscript.123.js

หรือ

myscript.js?updated=1234567890


9
โปรดทราบว่าพร็อกซีจำนวนมากจะไม่แคชไฟล์เมื่อมีสตริงข้อความค้นหา ดูคำตอบของเควิน Hakanson
chiborg

4
ฉันจะล้างแคชเมื่อ HTML ทั้งหมดถูกแคชได้อย่างไร มันจะไม่ส่งผลกระทบถึงแม้ว่าจะมีการเพิ่มหมายเลขเวอร์ชันเนื่องจาก HTML ที่แคชไว้โปรดช่วย
Nandakumar

หากฉันไม่สามารถล้างรายการแคชทำไมMDN ถึงบอกว่าฉันทำได้ ฉันพลาดอะไรไป ฉันลองสิ่งที่ MDN พูด แต่ไม่มีโชค
Sнаđошƒаӽ

41

ลองเปลี่ยน src ของไฟล์ JavaScript หรือไม่ จากนี้:

<script language="JavaScript" src="js/myscript.js"></script>

สำหรับสิ่งนี้:

<script language="JavaScript" src="js/myscript.js?n=1"></script>

วิธีนี้ควรบังคับให้เบราว์เซอร์ของคุณโหลดสำเนาใหม่ของไฟล์ JS


n = 1 ทำอะไรได้บ้าง
KyelJmD

มันไม่ได้ทำอะไรเลยนอกจากจะเป็นสิ่งที่แตกต่าง มันอาจเป็น? 12345 หรือ? Kyle
Oneezy

ดังนั้นต้องเปลี่ยนชื่อไฟล์ด้วยหรือไม่ หรือเพียงแค่เส้นทาง src ที่ต้องเปลี่ยน?
เฟร็ด A

20

นอกเหนือจากการแคชทุกชั่วโมงหรือทุกสัปดาห์คุณอาจแคชตามข้อมูลไฟล์

ตัวอย่าง (ใน PHP):

<script src="js/my_script.js?v=<?=md5_file('js/my_script.js')?>"></script>

หรือแม้แต่ใช้เวลาในการแก้ไขไฟล์:

<script src="js/my_script.js?v=<?=filemtime('js/my_script.js')?>"></script>

3
ฉันสามารถตรวจสอบว่าฉันเข้าใจสิ่งนี้ถูกต้องหรือไม่: ด้วยตัวเลือก 1 เมื่อไฟล์เปลี่ยนแปลง md5 checksum hash จะเปลี่ยนจากนั้นเปลี่ยน url เบราว์เซอร์จะเห็น URL ใหม่และเริ่มต้นการโหลดไฟล์ใหม่ เซิร์ฟเวอร์รับข้อมูลที่ผนวกเข้ากับ url จะถูกละเว้น หากเป็นกรณีนี้เนียนสวยเถอะ
โคลินรองเท้าหุ้มส้น

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

2
การใช้การตรวจสอบเป็นความคิดที่ดี แต่ควรทำถูกต้อง การคำนวณทุกคำขอสำหรับทุกไฟล์จะทำให้ประสิทธิภาพของคุณดีขึ้นอย่างมาก การสืบค้นไม่ดีสำหรับการแคชด้วยดูคำตอบอื่น ๆ การใช้งานที่ถูกต้องคือการเพิ่ม checksum (ส่วนหนึ่งของ?) หรือหมายเลขรุ่นต่อท้ายชื่อไฟล์และใช้ชื่อใหม่นี้แทน (คุณสามารถใช้สคริปต์สร้างเพื่อทำสิ่งนี้โดยอัตโนมัติในการปรับใช้) ดู แสม , รอบและusemin
Frizi

10

คุณสามารถบังคับให้โหลดรหัสซ้ำทุก ๆ ชั่วโมงเช่นนี้ใน PHP:

<?php
echo '<script language="JavaScript" src="js/myscript.js?token='.date('YmdH').'">';
?>

หรือ

<script type="text/javascript" src="js/myscript.js?v=<?php echo date('YmdHis'); ?>"></script>

1
สวัสดี "v" และ "โทเค็น" หมายถึงอะไร
GMsoF

4
@GMsoF ที่เป็นเพียงพารามิเตอร์รับเพิ่มเติมซึ่งใช้ (ในกรณีนี้) เพื่อบอกเบราว์เซอร์ว่าเป็นไฟล์ "แตกต่าง" เพื่อให้เบราว์เซอร์จะยกเลิกเวอร์ชันแคชและโหลดไฟล์นี้แทน สิ่งนี้มักใช้กับ "วันที่แก้ไขล่าสุด" ของไฟล์ ฉันหวังว่านี้จะทำให้ความรู้สึก ;-)
Jelmer

6

วางสิ่งนี้ไว้ท้ายเทมเพลตของคุณ:

var scripts =  document.getElementsByTagName('script');
var torefreshs = ['myscript.js', 'myscript2.js'] ; // list of js to be refresh
var key = 1; // change this key every time you want force a refresh
for(var i=0;i<scripts.length;i++){ 
   for(var j=0;j<torefreshs;j++){ 
      if(scripts[i].src && (scripts[i].src.indexOf(torefreshs[j]) > -1)){
        new_src = scripts[i].src.replace(torefreshs[j],torefreshs[j] + 'k=' + key );
        scripts[i].src = new_src; // change src in order to refresh js
      } 
   }
}

1
โปรดให้คำอธิบายเกี่ยวกับวิธีการแก้ปัญหาของคุณ
Gabriel Espinoza

@GabrielEspinoza เขาโหลดไฟล์ซ้ำโดยใช้ javascript ซึ่งทำให้แคชได้รับการอัปเดต
Neo Morina

6

ลองใช้สิ่งนี้

 <script language="JavaScript" src="js/myscript.js"></script>

สำหรับสิ่งนี้:

 <script language="JavaScript" src="js/myscript.js?n=1"></script>

5

นี่คือตัวอย่างของสิ่งที่ฉันใช้สำหรับโครงการล่าสุดของฉัน

จากตัวควบคุม:

if ( IS_DEV ) {
    $this->view->cacheBust = microtime(true);
} else {
    $this->view->cacheBust = file_exists($versionFile) 
        // The version file exists, encode it
        ? urlencode( file_get_contents($versionFile) )
        // Use today's year and week number to still have caching and busting 
        : date("YW");
}

จากมุมมอง:

<script type="text/javascript" src="/javascript/somefile.js?v=<?= $this->cacheBust; ?>"></script>
<link rel="stylesheet" type="text/css" href="/css/layout.css?v=<?= $this->cacheBust; ?>">

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

นอกจากนี้ยังให้การป้องกันแคชทุกครั้งที่โหลดหน้าเว็บในขณะที่อยู่ในสภาพแวดล้อมการพัฒนาเพื่อให้นักพัฒนาไม่ต้องกังวลกับการล้างแคชสำหรับทรัพยากรใด ๆ (javascript, css, ajax call)


5

หรือคุณสามารถอ่านไฟล์ js โดยเซิร์ฟเวอร์ด้วย file_get_contets แล้วใส่ echo ลงในส่วนหัวของเนื้อหา js


4

บางที"การล้างแคช"อาจไม่ง่ายอย่างที่ควรจะเป็น แทนที่จะล้างแคชในเบราว์เซอร์ของฉันฉันรู้ว่า"แตะ"ไฟล์จะเปลี่ยนวันที่ของไฟล์ต้นฉบับที่แคชบนเซิร์ฟเวอร์ (ทดสอบบน Edge, Chrome และ Firefox) และเบราว์เซอร์ส่วนใหญ่จะดาวน์โหลดสำเนาสดใหม่ล่าสุดโดยอัตโนมัติ อะไรในเซิร์ฟเวอร์ของคุณ (รหัสกราฟิกมัลติมีเดียใด ๆ ด้วย) ฉันขอแนะนำให้คุณคัดลอกสคริปต์ล่าสุดบนเซิร์ฟเวอร์และ"ทำสิ่งที่สัมผัส"ก่อนที่โปรแกรมของคุณจะทำงานดังนั้นมันจะเปลี่ยนวันที่ของไฟล์ปัญหาทั้งหมดของคุณเป็นวันที่และเวลาล่าสุดจากนั้นดาวน์โหลดสำเนาใหม่ สู่เบราว์เซอร์ของคุณ:

<?php
    touch('/www/control/file1.js');
    touch('/www/control/file2.js');
    touch('/www/control/file2.js');
?>

... โปรแกรมที่เหลือของคุณ ...

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


1
ฉันชอบวิธีการนี้ แต่บางทีฉันอาจใช้สิ่งนี้ผิดด้าน? ไม่มีใครรู้ว่าจะเพิ่มสิ่งนี้ในการตั้งค่า WordPress? ฉันเพิ่มลงในไฟล์ functions.php พร้อมลิงก์โดยตรงไปยังไฟล์ JavaScript และ CSS แต่ฉันยังต้องทำการรีโหลดอย่างหนักเพื่อให้การเปลี่ยนแปลงสังเกตได้
flipflopmedia

1
สิ่งที่คุณต้องทำคืออยู่ที่ไดเรกทอรีหลัก HTML ของคุณแก้ไข index.php ของคุณเพื่อโทรหรือรันคำสั่ง Touch () ไปยังไฟล์ที่คุณต้องรีเฟรชและดาวน์โหลด ฉันมีปัญหากับไฟล์ภาพขนาดเล็กและไฟล์ js ที่ติดอยู่ในแคช ฉันได้ลองวิธีการส่วนใหญ่ที่อธิบายถึงการปลดปล่อยจากหน่วยความจำ แต่วิธีที่ดีที่สุดคือการโหลดวิธีที่ถูกต้องในปัจจุบัน คุณสามารถรู้ว่าเพียงแค่ทำ "Touch Thing" เพราะมันไม่ได้แก้ไขอะไรเลยในไฟล์เพียงแค่อัปเดตเวลาและวันที่ปัจจุบันเพื่อให้เบราว์เซอร์ของคุณคิดว่าไฟล์และปัญหาเวอร์ชันอื่นได้รับการแก้ไข ใช้งานได้กับเบราว์เซอร์ส่วนใหญ่
Luis H Cabrejo

3

ฉันมีปัญหาบางอย่างกับรหัสที่ yboussard แนะนำ วง j ภายในไม่ทำงาน นี่คือรหัสที่แก้ไขที่ฉันใช้ด้วยความสำเร็จ

function reloadScripts(toRefreshList/* list of js to be refresh */, key /* change this key every time you want force a refresh */) {
    var scripts = document.getElementsByTagName('script');
    for(var i = 0; i < scripts.length; i++) {
        var aScript = scripts[i];
        for(var j = 0; j < toRefreshList.length; j++) {
            var toRefresh = toRefreshList[j];
            if(aScript.src && (aScript.src.indexOf(toRefresh) > -1)) {
                new_src = aScript.src.replace(toRefresh, toRefresh + '?k=' + key);
                // console.log('Force refresh on cached script files. From: ' + aScript.src + ' to ' + new_src)
                aScript.src = new_src;
            }
        }
    }
}

3

หากคุณใช้ php สามารถทำได้:

 <script src="js/myscript.js?rev=<?php echo time();?>"
    type="text/javascript"></script>

6
คำถามนี้ไม่เพียงถามเมื่อสี่ปีที่แล้ว แต่ยังมีคำตอบที่ดีกว่าแม้ว่าจะไม่ได้รับการยอมรับ

4
นอกจากนี้วิธีนี้จะดาวน์โหลดไฟล์ใหม่ทุกครั้งโดยไม่คำนึงถึงหมายเลขการแก้ไขจริงหรือการเปลี่ยนแปลงที่ทำกับไฟล์ซึ่งจะปิดการใช้งานแคชอย่างมีประสิทธิภาพ
Antti29

2

Cache.delete ()สามารถใช้กับ chrome, firefox และ opera ใหม่ได้


นี่เป็นเพียงส่วนหนึ่งของ API บริการของคนงานใช่หรือไม่
BanksySan

@BanksySan จากเอกสาร MDN:You don't have to use it in conjunction with service workers, even though it is defined in the service worker spec.
Madbreaks

2

กรุณาอย่าให้ข้อมูลที่ไม่ถูกต้อง Cache apiเป็นประเภทของแคชที่แตกต่างจากแคชhttp

แคช HTTPจะทำงานเมื่อเซิร์ฟเวอร์ส่งส่วนหัวที่ถูกต้องคุณไม่สามารถเข้าถึงด้วย javasvipt

api ของแคชในทางกลับกันถูกไล่ออกเมื่อคุณต้องการมันเป็นประโยชน์เมื่อทำงานกับพนักงานบริการดังนั้นคุณสามารถตัดกันคำขอและตอบจากแคชประเภทนี้ดู: ilustration 1 ilustration 2 course

คุณสามารถใช้เทคนิคเหล่านี้เพื่อให้ผู้ใช้ของคุณมีเนื้อหาใหม่อยู่เสมอ:

  1. ใช้location.reload (จริง)สิ่งนี้ไม่ได้ผลสำหรับฉันดังนั้นฉันจะไม่แนะนำอีก
  2. ใช้Cache apiเพื่อบันทึกลงในแคชและตัดการร้องขอกับพนักงานบริการระวังด้วยสิ่งนี้เพราะถ้าเซิร์ฟเวอร์ส่งส่วนหัวแคชสำหรับไฟล์ที่คุณต้องการรีเฟรชเบราว์เซอร์จะตอบจากแคช HTTP ก่อน และถ้ามันไม่พบมันก็จะไปที่เครือข่ายดังนั้นคุณจึงสามารถจบลงด้วยไฟล์เก่า
  3. เปลี่ยน URL จากไฟล์ stactics ของคุณคำแนะนำของฉันคือคุณควรตั้งชื่อด้วยการเปลี่ยนแปลงเนื้อหาไฟล์ของคุณฉันใช้md5แล้วแปลงเป็นสตริงและ URL ที่เป็นมิตรและ md5 จะเปลี่ยนกับเนื้อหาของไฟล์ที่นั่นคุณ สามารถส่งส่วนหัวแคช HTTP ได้อย่างอิสระนานพอ

ฉันอยากจะแนะนำให้คนที่สามดู


2

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

(ในส่วนหัว)

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

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

ลิงก์นี้จะให้ตัวเลือกอื่น ๆ แก่คุณหากคุณต้องการ http://cristian.sulea.net/blog/disable-browser-caching-with-meta-html-tags/

หรือคุณสามารถสร้างปุ่มได้

<button type="button" onclick="location.reload(true)">Refresh</button>

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


1

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

<cfset fw.version = '001' />
<script src="/scripts/#fw.version#/foo.js"/>

3
OP ไม่ได้พูดถึง Coldfusion
marctrem

@VijayDev 404 สำหรับลิงก์ของคุณ
smarber

1
window.parent.caches.delete("call")

ปิดและเปิดเบราว์เซอร์หลังจากรันโค้ดในคอนโซล


1
โปรดอธิบายหน่อยสิว่า "call" ในรหัสด้านบนคืออะไร?
Anand Rockzz

@AnandRockzz เป็นไปไม่ได้แคช api เป็นเพียงแคชชนิดใหม่ที่สามารถจัดการได้ด้วย javascipt ดังนั้นเพื่อที่จะลบบางสิ่งออกจากที่นั่นคุณได้บันทึกไว้ก่อนที่จะเห็น developer.mozilla.org/en-US/docs/ เว็บ / API / แคช
John Balvin Arias

1

window.location.reload(true)ดูเหมือนว่าจะถูกคัดค้านโดยมาตรฐาน HTML5 วิธีหนึ่งที่จะทำเช่นนี้โดยไม่ต้องใช้สายแบบสอบถามคือการใช้Clear-Site-Dataส่วนหัวซึ่งดูเหมือนว่าจะถูกมาตรฐาน


0

ทำให้แคชของเบราว์เซอร์ลิงก์เดียวกันคุณควรเพิ่มเลขสุ่มสิ้นสุดของ url new Date().getTime()สร้างหมายเลขอื่น

เพียงเพิ่มnew Date().getTime()จุดสิ้นสุดลิงก์เช่นเดียวกับการโทร

'https://stackoverflow.com/questions.php?' + new Date().getTime()

เอาท์พุท: https://stackoverflow.com/questions.php?1571737901173


ยินดีต้อนรับสู่ SO! คำตอบของคุณไม่ชัดเจน โปรดแก้ไข คำตอบประเภทนี้ตามลิงก์ควรให้ความเห็นในกรณีที่ลิงก์หายไป
David García Bodego
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.