天天看點

艾偉:詳解AJAX核心 —— XMLHttpRequest 對象 (下)

上一篇關于XMLHttpRequest 對象發送對伺服器的請求隻說到了用Get方式,沒有說Post方式的。那是因為要說Post方式就需要先說另外一個東西,那就是DOM(Document Object Model)文檔對象模型。JavaScript通過DOM讀取、改變或者删除 HTML、XHTML 以及 XML中的元素,可以重構整個 HTML 文檔。可以添加、移除、改變或重排頁面上的項目,而且這樣的操作會馬上顯示在頁面上。另外,所有浏覽器執行W3C 釋出的 DOM 标準規範,DOM的跨浏覽器的相容問題也就不是問題了。

先來看看下面的這個HTML文檔

<html>

  <head>

    <title>文档标题title>

  head>

  <body>

    <h1>我的标题h1>

    <a href="">我的链接a>

  body>

html>

這個HTML文檔轉換成對象表示就是下圖這個DOM樹。

從這個樹就能看出來,HTML中的每一項對應到DOM中都是一個節點,包括屬性和文本。

而每個節點都包含某些資訊的屬性。節點屬性包括下面三種:

nodeName(節點名稱)

nodeValue(節點值)

nodeType(節點類型)

nodeName

nodeName 屬性含有某個節點的名稱。

元素節點的 nodeName 是标簽名稱

屬性節點的 nodeName 是屬性名稱

文本節點的 nodeName 永遠是 #text

文檔節點的 nodeName 永遠是 #document

注釋:nodeName 所包含的 XML 元素的标簽名稱永遠是大寫的

nodeValue

對于文本節點,nodeValue 屬性包含文本。

對于屬性節點,nodeValue 屬性包含屬性值。

nodeValue 屬性對于文檔節點和元素節點是不可用的。

nodeType

nodeType 屬性可傳回節點的類型。

主要常用節點類型有下面幾種:

元素節點類型是1

屬性節點類型是2

文本節點類型是3

文檔節點類型是9

使用DOM從取得DOM對象開始,看看怎麼通路DOM對象本身吧:

var domTree = document;

實際中我們更多的是直接使用 document 而來表示DOM對象。

從這裡開始,我們可以通過DOM對象通路文檔中的所有内容了。

再看看取的節點所使用的方法吧。

我們重點來看看getElementById() 和 getElementsByTagName()

document.getElementById("ID");  傳回通過 ID 指定的節點;

document.getElementsByTagName("标簽名稱"); 傳回指定的标簽名所有的節點(作為一個節點清單);

下面做一個簡單的例子,看看怎麼使用DOM以Post方法發送内容給伺服器,并把結果顯示出來。

看看這個HTML頁面

 <head>

  <title>AJAX and the DOMtitle>

 head>

 <body>

  <div id="Content">

   <input type="text" id = "name" value="myname" />

   <br/>

   <input type="text" id = "age" value="99" />

  div>

  <input type="button" value="Tell me!" />

  <div id = "result">div>

 body>

我們的目标就是簡單的把名字和年齡發送給伺服器進行處理,并把結果顯示在result這個DIV中。

XMLHttpRequest 對象 就使用上一篇的方法建立,這裡就不再多說了。

首先就是要取得名字和年齡的值

var name = document.getElementById("name").value; //取名字

var age = document.getElementById("age").value;  //取年齡

然後再将名字和年齡按照通信格式拼接

var info = name+"|"+age; //簡單的将姓名和年齡用豎線分割交給伺服器處理

好了,整理好要發送的内容,确定發送的位址,以及方式;看,這裡就是用Post方式了,位址自然就是要進行處理伺服器的位址了。

xmlhttp.open("Post","http://localhost/WebForm1.aspx",true);

這個時候我們就可以使用send方法将info對象發送給伺服器了。

xmlhttp.send(info);

處理傳回的結果也很簡單了,直接把結果顯示在result中

var result = document.getElementById("result").firstChild;

xmlhttp.onreadystatechange = function (){

 if(xmlhttp.readyState == 4 && xmlhttp.status == 200){

  result.nodeValue = xmlhttp.responseText;

 }

}

順帶說一下,把結果顯示在result這個DIV中,為什麼是 getElementById("result").firstChild 而不是直接getElementById("result")。這就跟開始時說的DOM對象有關系了,前面也說過,在DOM中文本也是一個節點,這裡DIV中的文本就是result這個DIV的子節點,而又是唯一一個節點,是以用firstChild就可以取到了。

艾偉:詳解AJAX核心 —— XMLHttpRequest 對象 (下)
艾偉:詳解AJAX核心 —— XMLHttpRequest 對象 (下)

完整的頁面代碼

<head>

 <title>AJAX and the DOMtitle>

 <script language="JavaScript">

  var xmlhttp = false; //创建一个新变量 request 并赋值 false。使用 false 作为判断条件,它表示还没有创建 XMLHttpRequest 对象。 

  function CreateXMLHttp(){

   if(window.XMLHttpRequest){

    xmlhttp = new XMLHttpRequest();

   }

   else if(window.ActiveXObject)

   {

    xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); //较新版本的IE

    if(!xmlhttp) {

    xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); //较旧版本的IE

    }

   return xmlhttp;

  }

  xmlhttp = CreateXMLHttp();

  function send()

  {

   xmlhttp.open("Post","http://localhost/WebForm1.aspx",true);

   var name = document.getElementById("name").value; //取名字

   var age = document.getElementById("age").value;  //取年龄

   var info = name+"|"+age; //简单的将姓名和年龄用竖线分割交给服务器处理

   var result = document.getElementById("result").firstChild;

   xmlhttp.send(info);

   xmlhttp.onreadystatechange = function (){

    if(newxmlhttp.readyState == 4 && newxmlhttp.status == 200){

     result.nodeValue = newxmlhttp.responseText;

 script>

head>

<body>

 <div id="Content">

  <input type="text" id = "name" value="myname" />

  <br/>

  <input type="text" id = "age" value="99" />

 div>

 <input type="button" value="Test me!" onClick="send();" />

 <div id = "result">div>

body>

伺服器端就做最近簡單的處理,代碼如下:

<%@ Page language="c#" AutoEventWireup="true" %>

<script language="C#" runat="server">

public string result;

private void Page_Load(object sender, System.EventArgs e)

{

 // 在此处放置用户代码以初始化页面

 System.IO.StreamReader sr = new System.IO.StreamReader(Page.Request.Input

Stream,System.Text.Encoding.UTF8);

 string[] gets = sr.ReadToEnd().Split('|');

 result = string.Format(@"Your name is {0},{1} years old!",gets[0],gets[1]);

script>

<%=result%>

一個簡單的以Post方式發送的例子就完成了。

最後,在不同的情況需要使用setRequestHeader來修改請求頭來不是直接發送就可以了。

繼續閱讀