XMLHTTP בצד לקוח

‏ • 28 בפברואר, 2004

הרבה פעמים נשאלת בפורומים השאלה "איך אני יכול לעדכן או לשלוף מידע מבסיס הנתונים מבלי לרענן את הדף"?
מכיוון ששליפת נתונים בבסיס הנתונים נעשה בצד השרת, והשרת בעצם סיים כבר את פעולתו כאשר הדף מוצג ללקוח, לא ניתן לעשות זאת ללא פניה נוספת לשרת. אבל אין זה אומר שחייבים לרענן את הדף.
שתי הטכניקות הנפוצות לביצוע מטרה זו הן שימוש ב-XMLHTTP, או ב-download behavior.
במאמר זה נדגים את השימוש בשיטה הראשונה – XMLHTTP.

נדמיין לעצמינו מילון מונחים פשוט, המכיל מונחים ופירושם. באפשרותינו לשלוף ולהציג בדף את כל המונחים במילון, אך במקרה בו שי שלנו עשרות או מאות מונחים – הפעולה עלולה לקחת זמן רב, והגולש שלנו יאלץ להמתין לטעינת כל הדף גם אם הוא מעוניין לקרוא מונח יחיד.
כמובן שיכולנו להציג את רשימת המונחים, כאשר שם המונח הוא בעצם קישור לדף המציג את פירושו. אבל מה אם אנחנו רוצים לחסוך לגולש שלנו את המעבר לעמוד אחר? כאן נכנס לפעולה ה-XMLHTTP.

במאמר נדגים שני סוגים של חיפושי מונחים – מונח בודד, אשר אותו בוחר הגולש מתיבת בחירה, ואני מציגים לו את פירוש המונח שבחר, או חיפוש של מספר ערכים, כאשר הגולש בוחר אות כלשהי, ואנחנו מציגים לו את כל המונחים המתחילים באותה אות.

הערות:


  • הקודים במאמר זה חלקיים בלבד כדי לחסוך במקום. את הקוד המלא ניתן להוריד ע"י לחיצה על הקישור בסוף המאמר.
  • קוד ה-asp במאמר כתוב ב-JS, אבל ניתן כמובן לכותבו גם ב-VBS.

להרצת הדוגמא לחץ כאן

מבנה בסיס הנתונים

מבנה ה-DB מאוד פשוט. יש לנו טבלה אחת בשם tbl_Terms, ובתוכה שלושה שדות:

  • Id – מספר זיהוי הרשומה
  • sTerm – שם המונח
  • sText – פירוש המונח

הדף הראשי

קוד ה-asp בדף הראשי שלנו מאוד פשוט:










1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27  








<body>
<%
var connDSN="Provider=Microsoft.Jet.OLEDB.4.0; Data Source = " +
            Server.MapPath("/Data/examples.mdb")
var oCon =Server.CreateObject("ADODB.connection");
oCon.Open (connDSN);
var SQL="SELECT Id, sTerm FROM tbl_Terms ORDER BY sTerm"

for (i=97;i<123;i++)
    Response.write ("<span class= \"Link\" onclick=\"fShowByLetter('"
    + String.fromCharCode(i).toUpperCase() + "')\">"
    String.fromCharCode(i).toUpperCase() + 
"</span> ")
%>
<select onchange="fShowTerm(this.value)">
<option value="">Select a Term</option>
<%=fComboOptions(SQL)%>
</select>
<hr>
<div id="oTermDiv" style="width:500px"></div>

</body>
</html>
<%
oCon.Close
oCon = null;
delete oCon;
%>




  • שורות 3-5: פתיחת החיבור לבסיס הנתונים
  • שורות 8-9: הצגת כל אותיות ה-ABC כך שבלחיצה על אחת מהן נוכל להציג את כל המונחים המתחילים באותה אות.
  • שורה 11: תיבת הבחירה שתשמש אותנו לבחירת ערכים בודדים
  • שורה 13: קריאה לפונקציה שבונה את ה-options של תיבת הבחירה (את הקוד המלא של הפונקציה ניתן לראות בקבצים להורדה). הערך של ה-option יהיה ה-ID של המונח, והטקסט שלו – שם המונח.
  • שורה 16: ה-div בתוכו יוצגו התוצאות

קבלת ערך בודד

כזכור, מוצגת עכשיו בדף תיבת בחירה עם שמות המונחים, ואנחנו רוצים להציג את פירוש המונח כל פעם שאנו בוחרים מונח מהרשימה. לכן הגדרנו שבארוע onchange של ה-select תופעל הפונקציה fShowTerm, שתקבל כפרמטר את ה-ID של האופציה שנבחרה.

הפונקציה fShowTerm:












1
2
3
4  








function fShowTerm(id){
    if(!id){oTermDiv.innerHTML="";return}
    oTermDiv.innerHTML=GetXmlResponse("id="+id, "XMLHTTPReciver.asp",true)
}




  • שורה 2: בדיקה האם נבחר id כלשהו
  • שורה 3: קריאה לפונק' GetXmlResponse והצגת הערך המוחזר שלה בתוך ה-div.

הפונקציה GetXmlResponse:

פונקציה זו היא האחראית להפעיל את הדף בצד שרת שישלוף מבסיס הנתונים את פירושו של המונח שבחרנו. הפונק' מקבלת שלושה פרמטרים:

  • URL – הדף בצד השרת אותו אנחנו רוצים להפעיל. הוא זה שיבצע את השליפה בפועל מבסיס הנתונים.
  • DataToSend – הנתונים אותם אנחנו רוצים לשלוח לדף זה.
  • bText – פרמטר בוליאני המציין האם אנחנו רוצים לקבל את התשובה שלנו בפורמט XML (בשביל תשובות מרובות) או בפורמט Text (וזה בעצם מה שאנחנו מעוניינים בו כרגע).











1
2
3
4
5
6
7
8  








function GetXmlResponse(DataToSend, URL, bText)
{
    var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
    xmlhttp.Open("POST",URL + '?rand='+ Math.random() ,false);
    xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    xmlhttp.send(DataToSend);
    return(bText?xmlhttp.responseText:xmlhttp.responseXML);
}




  • שורה 3: יצירת אובייקט ה-xmlhttp (למידע נוסף על האובייקט לחץ כאן)
  • שורה 4: פתיחת ה-URL שביקשנו. אנחנו מצרפים גם ערך אקראי מכיין של-xmlhttp יש נטיה לטעון דפים מזכרון המטמון. הערך האקראי מכריח אותו לטעון את הדף מהשרת.
  • שורה 5: קביעת ה-header של הבקשה שנשלחת
  • שורה 6: שליחת הנתונים (DataToSend)
  • שורה 7: קבלת התשובה והחזרתה בצורת text או XML, בהתאם לפרמטר bText שקיבלה הפונקציה.
כמו שראינו, הפונק fShowTerm קוראת ל- GetXmlResponseושולחת לה שלושה פרמטרים:

  • URL: XMLHTTPReciver.asp
  • DataToSend: "id="+id (שהוא ה-id של הרשומה שנבחרה בתיבת הבחירה)
  • bText: true (אנחנו רוצים את התשובות בפורמט טקסט.
עכשיו כשהבנו איך הפונקציות עובדות, נותר לנו רק לעיין בדף XMLHTTPReciver.asp, המבצע את השליפה מבסיס הנתונים.










1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24  








<%@ Language=JavaScript Codepage=1255%>
<%
var id=Request("id")()
if(!id || isNaN(id)){
    Response.Write("Invalid Id")
    Response.End
}

var connDSN="Provider=Microsoft.Jet.OLEDB.4.0; Data Source = " +
     Server.MapPath("/Data/examples.mdb")
var oCon =Server.CreateObject("ADODB.connection");
oCon.Open (connDSN);
var oRs=Server.CreateObject("ADODB.Recordset")
var SQL="SELECT sText FROM tbl_Terms WHERE ID="+id
oRs.Open(SQL,oCon)
if(oRs.EOF) Response.Write("Record not found")
else Response.Write(oRs("sText").value)
oRs.Close
oRs = null;
delete oRs;
oCon.Close
oCon = null;
delete oCon;
%>




  • שורות 3-7: קבלת ה-id ובדיקות קלט
  • שורות 9-13: הגדרת המשתנים ופתיחת החיבור לבסיס הנתונים
  • שורות 14-15: שליפת פירוש המונח שאת ה-id שלו קיבלנו
  • שורות 16-17: בדיקה האם המונח נמצא, והצגתו בדף

קבלת ערכים מרובים

נעבור לאופציית החיפוש השניה – חיפוש לפי אות.
על הדף מוצכות לנו כל אותיות ה-ABC כאשר לחיצה על כל אחת מהן קוראת לפונקציה fShowByLetter ושולחת לה את האות בה בחרנו.

הפונקציה fShowByLetter












1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22  








function fShowByLetter(letter){
    if(!letter){oTermDiv.innerHTML="";return}
    var xmlDoc = new ActiveXObject("microsoft.XMLDOM")
    xmlDoc.validateOnParse = true;
    xmlDoc.load(GetXmlResponse("letter="+letter, "XMLHTTPReciverByLetter.asp", false))
 
    var XMLroot = xmlDoc.documentElement, str;
    if(!XMLroot.childNodes.length) str="No Matches"
    else{
        str="<table border='1'><tr>\n"
        str+="<th>Term</th><th>Text</th>\n"
        str+="</tr>\n"
        for (i = 0; i <= XMLroot.childNodes.length1; i++) {
            str+="<tr>\n"
            str+="<td>"+XMLroot.childNodes.item(i).childNodes.item(0).text+"</td>"
            str+="<td>"+XMLroot.childNodes.item(i).childNodes.item(1).text+"</td>"
            str+="</tr>"
        }
        str+="</table>"
    }
    oTermDiv.innerHTML=str
}




  • שורה 2: בדיקה האם אכן קיבלנו אות כלשהי
  • שורה 3: יצירת אובייקט XMLDOM
  • שורה 4: טעינת קוד ה-XML שקיבלנו מהפונקציה GetXmlResponse (הפעם שלחנו לה בתור bText את הערך false, שאומר לה להחזיר לנו את הנתונים בפורמט XML )
  • שורה 7: בדיקה האם אכן קיבלנו נתונים כלשהם בחזרה
  • שורות 8-19: בניית הטבלה לתצוגת הערכים. על קריאת קובץ XML והצגתו ניתן לקרוא במאמר הזה: https://www.webmaster.org.il/article.asp?id=110
  • שורה 20: תצוגת הנתונים בתוך ה-div שיועד לכך.

הדף XMLHTTPReciverByLetter.asp












1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38  








<%@ Language=JavaScript Codepage=1255%>
<%
Response.ContentType = "text/xml"
var letter=Request("letter")(), sFinal="<?xml version=\"1.0\"?><Terms>"

var connDSN="Provider=Microsoft.Jet.OLEDB.4.0; Data Source = "+Server.MapPath("/Data/examples.mdb")
var oCon =Server.CreateObject("ADODB.connection");
oCon.Open (connDSN);
var oRs=Server.CreateObject("ADODB.Recordset")
var SQL="SELECT sTerm, sText FROM tbl_Terms WHERE sTerm Like '"+letter+"%'"
oRs.Open(SQL,oCon)
while (!oRs.EOF){
    sFinal+="<Term>"
    sFinal+="<sTerm>"+fBadChars(oRs("sTerm").value)+"</sTerm>"
    sFinal+="<sText>"+fBadChars(oRs("sText").value)+"</sText>"
    sFinal+="</Term>"
    oRs.MoveNext()
}
sFinal+="</Terms>"
oRs.Close
oRs = null;
delete oRs;
oCon.Close
oCon = null;
delete oCon;
Response.Write(sFinal)

function fBadChars(str){
    if(str){
        str=str.replace(/&/g,"&amp;")
        str=str.replace(/>/g,"&gt;")
        str=str.replace(/</g,"&lt;")
        str=str.replace(/\"/g,"&quot;")
    }
    return str||"";
}

%>




  • שורה 3: ציון שפלט הדף היה בפורמט XML
  • שורות 4-8: הגדרה ואתחול ומשתנים, ופתיחת החיבור לבסיס הנתונים
  • שורות 10-11: שליפת כל המונחים ששם מתחיל באות שבחרנו
  • שורות 12-19:מעבר על הרקורדסט ובניית קוד ה-XML (הפונקציה fBadChars מבצעת החלפה של תווים בעייתיים לקוד ה-XML. ניתן לראות אותה בקוד להורדה בסוף המאמר).
וזה הכל 🙂
להורדת הדוגמא לחץ כאן

תכנות נעים!

תגיות: , , , , ,

תגובות בפייסבוק