Tag Archive expires

jQuery: Ajax Cache

ต้องการเก็บข้อมูลส่วนที่ใช้บ่อยๆ ไว้ในฝั่ง user (browser) นั่นละ จะได้ลดการ query แต่ข้อมูลมันมีการเปลี่ยนแปลงด้วย ที่เก็บข้อมูลระยะยาวได้ในฝั่ง browser กลับออกแบบให้ localStorage เก็บข้อมูลถาวรโดยไม่มีการ expires เหมือน cookie ทำให้ต้องเขียน code จัดการเพิ่ม

<!doctype html>
<html>

<head>
    <meta charset="utf-8">
    <title>Ajax: localStorage</title>
</head>

<body>
    <h1>localStorage</h1>
    <div class="col-sm-12" id="datasA"></div>
    <div class="col-sm-12" id="resultA"></div>
    <script src="../vendor/components/jquery/jquery.min.js"></script>
    <script>
        $(function() {

            function getDatas() {
                let cacheKey = 'memories';

                if (cacheKey in localStorage) {
                    let datas = JSON.parse(localStorage.getItem(cacheKey));

                    // if expired
                    if (datas['expires'] < Date.now()) {
                        localStorage.removeItem(cacheKey);

                        getDatas()
                    } else {
                        setDatas(datas);
                    }
                } else {
                    $.ajax({
                        "dataType": "json",
                        "success": function(datas, textStatus, jqXHR) {
                            let today = new Date();

                            datas['expires'] = today.setDate(today.getDate() + 7) // expires in next 7 days

                            setDatas(datas);

                            localStorage.setItem(cacheKey, JSON.stringify(datas));
                        },
                        "url": "http://localhost/phunsanit/snippets/PHP/json.json_encode.php",
                    });
                }
            }

            function setDatas(datas) {
                // display json as text
                $('#datasA').text(JSON.stringify(datas));

                // your code here
                let html = '';
                $.each(datas.datas, function(index, value) {
                    html += '<br>' + index + ' = ' + value;
                });
                $('#resultA').html(html);

            }

            // call
            getDatas();

        });
    </script>
</body>

</html>

ข้อมูลที่ call ผ่าน ajax จะโดนเก็บใน localStorage แต่เวลาใช้ก็จะเอามาเทียบ expires ก่อน ถ้ายังไม่หมดอายุก็เอามาใช้ ถ้าหมดอายุไปแล้วก็ call ใหม่ ลองดัดแปลงดูให้เหมาะกับงานดูครับ

PHP: no-cache css javascript

ตามคำแนะนำในการทำเว็บให้เร็วคือให้แยกไฟล์ภาพ, css และ javascript ออกมาเพราะว่าไฟล์พวกนี้แทบจะเหมือนๆ กันทุกๆหน้า และเปลี่ยนไม่บ่อยนัก การ set server จึงกำหนดให้ทางฝั่ง browser จดจำ static content (css, images,js files) พวกนี้เอาไว้ จะได้ไม่ต้องโหลดไฟล์พวกนี้ใหม่ ทำให้สิ้นเปลือง (สิ้นเปลือง bandwide แบนด์วิธอันล้ำค่าและมีราคาที่เช่ามาจาก isp และ cpu, ram ที่ใช่จัดการจ่ายไฟล์จาก server ไปให้บราวน์เซอร์ของยูเซอร์)

ปัญหาก็คือ เมื่อเราแก้ไฟล์ image, css หรือ javascript อัพโหลดขึ้นไปบน server แล้วแต่ user ยังได้รับไฟล์ version เดิมๆ อยู่ ที่นิยมกันก็คือ ใส่ตัวแปรแบบสุ่มหรือเวลาตามหลังชื่อไฟล์ เช่น

<link href="styles.css?ts=150151" rel="stylesheet" type="text/css">
...
<script src="scripts.js?ts=150151">
...
<img src="logo.png?ts=150151">

เมื่อต้องการให้ใช้ไฟล์ version ใหม่ก็เปลี่ยนค่าของ ts เป็นค่าอื่น ตัว browser จะถือว่าเป็นคนละไฟล์กับไฟล์เดิมที่เก็บไว้ใน cache ของมันเอง ปัญหาก็คือถ้ามีไฟล์พวกนี้ 100 จุด หรือ 1000 จุดก็ต้องไล่แก้ทั้งหมดให้เหมือนๆกันถึงจะเปลี่ยนไฟล์ทุกตัวให้เป็นตัวใหม่พร้อมๆกัน อาจจะทำเป็น global variable หรือใช้ function จัดการให้แต่มันซับซ้อนเกินไป

อีกวิธีที่ทำได้ง่ายแต่ได้ผลกับทุกๆ ไฟล์คือใช้

header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');

เมื่อต้องการให้ browser โหลดไฟล์ใหม่อีกครั้ง โดยใส่ใน header ของเว็บ

อ่านเพิ่มเติม HTTP Caching