網友DD04問到$.ajaxSetup({ cache: false })的用途,我寫了一個小範例說明:

<%@ Page Language="C#" %>
<script runat="server">
    protected void Page_Load(object sender, EventArgs e)
    {
        if (Request["m"] == "t" )
        {
            Response.ContentType = "text/plain";
            System.Threading.Thread.Sleep(2000);
            Response.Write("Time: " + DateTime.Now.ToString("HH:mm:ss.fff") + "\n");
            Response.Write("Method: " + Request.HttpMethod + "\n");
            Response.Write("QueryString: " + Request.Url.Query + "\n");
            Response.Write("PostData: ");
            foreach (string key in Request.Form.Keys)
                Response.Write("\n" + key + "->" + Request.Form[key]);
            Response.End();
        }
    }
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>jQuery Ajax Cache Demo</title>
    <script src="../js/jquery-1.3.2.js" type="text/javascript"></script>
    <script type="text/javascript">
        $(function() {
            //$.ajaxSetup({ cache: false });
            $("#btnPostTest").click(function() {
                $.post("default.aspx", { m: "t" }, showResult);
            });
            $("#btnGetTest").click(function() {
                $.get("default.aspx", { m: "t" }, showResult);
            });
            function showResult(d) {
                alert(d);
            }
        });
    </script>
</head>
<body>
    <input type="button" id="btnPostTest" value="Post Test"/>
    <input type="button" id="btnGetTest" value="Get Test"/>
</body>
</html>

以上的程式碼可以存成default.aspx後實際跑來玩(記得要校正jquery.1.3.2.js的網址)。在網頁裡我做了兩顆按鈕,按下後會分別觸發$.get()及$.post(),而呼叫的對象就是default.aspx本身。在Page_Load()裡有段邏輯,當Request["m"] == "t"時不顯示網頁,而是將Request相關資訊Response.Write回去給Javascript端。為了突顯Cache效應,我特別放了一個Thread.Sleep(2000),也就是說,每次執行時,要停頓兩秒後才會得到結果。

首先你可以按兩次Post Test,每次應該都會在兩秒後得到結果。接著按兩次Get Test試試,第一次測試跟Post Test差不多,兩秒後得到結果(此時留意一下結果中的時間 Time: HH:mm:ss.fff),但第二次按鈕的結果很有趣,按下後不需等待兩秒,結果就立即彈出,而其中顯示的時間還跟第一次傳回的值完全相同。這證明了$.get()預設會啟用Cache功能,同樣的Request第二次不會真的送出,而是直接由Cache取回結果。

接著,我們將$.ajaxSetup()前方的//封印解除,再測試一次。這回不管按Get Test幾次,每次都要等兩秒才會得到結果,表示結果不是來自Cache,而是真的送至後端執行。由傳回結果,我們可以發現QueryString中被加了料:

Time: 12:38:59.985
Method: GET
QueryString: ?_=1243921137980&m=t
PostData:

當我們設定cache=false時,jQuery在我們每次發出Request時,會補上一個參數"_",而其內容是每次皆不同的亂數,這是Javascript端很常見的迴避Cache技巧。由於參數值不相同,每次Request都被視為不同,就能避開Cache裡的舊資料,強迫每次都將Request送至Server端執行。

呼叫$.ajax()時可以指定cache參數,在$.get()時則無從設起,因此範例中用$.ajaxSetup()設定全域適用的cache選項。

在實務上,用$.get()與後端溝通時要嚴防CSRF漏洞(補充說明),可以的話,最好改用$.post方式為之。


Comments

# by DD04

謝謝黑暗大大提供的例子解說,也比較瞭解 $.ajaxSetup({ cache: false }); 的用意是做什麼的!! 所以使用 JQuery 在做 Ajax 的時候,透過「$.ajax()」或「$.post()」這兩個方式來做,是會比較安全且保險的囉!!?

# by coac

一直不明白后面_参数是怎么回事,今天终于明白了

# by 罗洁琼

学习,不过还是有点模糊

# by Henry

多謝分享~

Post a comment