謙卑式jQuery檢核範例–Remote
2 |
這篇是Unobtrusive Client Validation的續集。覺得Unobtrusive唸起來太繞舌,硬要直譯成"不唐突的; 不冒昧的; 謙虛的;不引人注目的"好像也沒有比較簡短有力,於是在"低調"跟"謙恭"兩個詞間猶豫了一下,最後捨通俗就氣質,決定將Unobtrusive翻成帶點文學味的"謙恭",也算配合本站技術文章常暴走突變成詩歌散文的獨特風格。(謎之聲: 有些人就是咬文嚼字成性沒錯啦! 但文章總是有錯字是怎麼回事?) PS: 斟酌了一下,擔心謙恭太過文縐縐,有人看不懂,決定改成"謙卑",或者有人覺得"謙恭"比較好?
這回介紹如何透過謙卑式寫法設定remote規則,也就是將欄位內容以HttpRequest方式送至ASP.NET Server端進行驗證的範例:
<%@ Page Language="C#" %>
<!DOCTYPE html>
<script runat="server">
void Page_Load(object sender, EventArgs e)
{
if (Request.HttpMethod == "POST" && Request["mode"] == "check_member")
{
if (string.IsNullOrEmpty(Request["tExtra1"]) ||
string.IsNullOrEmpty(Request["tExtra2"]))
//檢核失敗傳回false會顯示data-val-remote指定的訊息
Response.Write("false");
else
{
string[] members = { "Jeffrey", "Darkthread", "SoundOfMystery" };
string tRemote = Request["tRemote"];
if (members.Contains(tRemote)) //檢核過關傳回true
Response.Write("true");
else if (tRemote == "Shit") //檢核失敗可傳回指定訊息覆寫原錯誤訊息
Response.Write(@"""不要說髒話!"""); //傳回自訂訊息時需加雙引號
else //tRemote非members裡的元素,檢核失敗傳回false
Response.Write("false");
}
Response.End();
}
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Unobstrusive JS Validation Demo</title>
<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.6.2.js"
type="text/javascript"></script>
<script src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.8.1/jquery.validate.js"
type="text/javascript"></script>
<script src="http://ajax.aspnetcdn.com/ajax/mvc/3.0/jquery.validate.unobtrusive.js"
type="text/javascript"></script>
<style type="text/css">
body,input { font-size: 9pt; }
.input-validation-error { border: 1px solid #ff0000 }
.input-validation-valid { border: 1px solid #00ff00 }
.field-validation-error { color: #ff0000 }
.field-validation-valid { display: none }
.validation-summary-errors { font-weight: bold; color: #ff0000 }
.validation-summary-valid { display: none }
</style>
</head>
<body>
<form id="form1" runat="server">
<div>
<input type="text" id="tExtra1" name="tExtra1" value="1" style="width:20px;" />
<input type="text" id="tExtra2" name="tExtra2" value="2" style="width:20px;" />
<input type="text" id="tRemote" name="tRemote" data-val="true"
data-val-required="不可空白" data-val-remote="查無會員編號或前兩欄空白"
data-val-remote-url="UnobJsVald.aspx?mode=check_member"
data-val-remote-type="POST" data-val-remote-additionalfields="tExtra1,tExtra2"
/>
<span data-valmsg-for="tRemote"></span>
</div>
<input type="submit" id="send" value="Send" />
</form>
</body>
</html>
簡單介紹remote相關參數:
- data-val-remote 為檢核失敗的訊息(Server端也可傳回訊息字串取代之)
- data-val-remote-url 為檢核網頁程式的網址
- data-val-remote-type 可為POST或GET(預設為GET),若不想傳送內容出現在URL,建議用POST
- data-val-remote-additionalfields 要額外多傳的欄位名稱,可用","分隔指定多欄,若沒有就不用給
在Server端,用Request["fieldName"]可以承接前端傳來的欄位內容,檢核成功時Response.Write("true"),失敗則Response.Write("false"),若失敗時要另傳特定錯誤訊息,則可Response.Write("\"訊息內容\"")。 (因前端會用JSON解析傳回內容,故記得前後加上雙引號才會被轉型成字串。)
另外我又做了些研究: 將tExtra1, tExtra2移除,並將remote-type改為GET,使用IE9 Dev Tools觀察操作期間的HttpRequest發送行為:
注意到了嗎? 第一次送出ASP.NET進行檢核後,之後每輸入一個字元,在keyup事件時就會觸發送出一個Request! 剛開始我頗為驚慌,認為如此豈不將送出一堆多餘Request,形同對Server進行DOS攻擊? 但仔細探究jQuery.validation原始碼,才發現其中內含精巧Pending調節設計,在Server端還沒有回應前,會放棄該期間原本要發送的Request,並不會產生瘋狂連送灌爆Server的舉動。
為了驗證Pending機制的功效,在Server端做點修改,在Response.End()前加入一行System.Threading.Thread.Sleep(500);,延遲0.5秒才回應。此時HttpRequest發送狀況變成:
當送出tRemote=J,檢核需耗時0.5秒,其間輸入的e, f字元並沒有觸發Request,直到取得回應後再輸入f,才再送出tRemote=Jeff。由此觀之,jQuery.valdation能依Server端的回應效率調節送出Request的頻率。我認為這樣已經是十分優秀的設計,Server忙回應慢Request自然變少,不致壓垮Server;但若還是擔心它增加伺服器負載,則不妨在Server端用Thread.Sleep做調節,以一點延遲換取在大量使用者連線時降低負荷,應是簡單有效的改善方法。
PS: 這裡介紹的是非ASP.NET MVC 3環境下應用謙卑式客戶端檢核的做法,若為ASP.NET MVC3專案,已有內建的輔助機制,實做起來更簡單,細節可參考demo的介紹文章。
Comments
# by Ike
「data-val-remote-additionfields」 應為 「data-val-remote-additionalfields」
# by Jeffrey
to lke, 謝,已校正。