AJAX總結


  • 從WEB1.0開始講起

    十多年前,我們剛剛覺得網絡引起我們的注意的時候,那時的網站用戶量不像現在那么大,所以在1.0時代,多采用同步機制。我們隱約記得,注冊一個賬號通常需要反復提交,返回的信息會告訴你填入的信息哪里出現了錯誤,哪里不符合規范。注冊一個賬號常常需要刷新好多次頁面,這樣的不僅給服務器的效率產生阻礙,也不利於我們效率辦公。所幸的是,當時的並發量不如現在的巨大。如果現在仍然采用同步機制,大概這個網站要不是不受歡迎,要不就是經常掛掉。

                                            

 

                     (百度偷來的圖)

  • 我所認識的WEB2.0

    在不斷接觸2.0時代產品的同時,我們體驗到了極大的方便與效率。比如我們現在注冊的時候,按提交鍵肯定會一次注冊成功了。(在設計上多按一次按鍵就會少很多用戶量)這在現今社會快節奏的效應下,2.0時代完全符合現代人的品味。而2.0時代與1.0時代僅僅差別在於一個異步的HTTP提交方式--AJAX(Asynchronous Javascript And XML)。這個神奇的AJAX技術引領了一個時代的浪潮,而它並不是一種很大的技術框架,可以說它是一種“設計方式”。它的原理並不是那么困難,就是異步地提交一個標准的HTTP請求。而它發起的請求,通常不需要用戶去點擊瀏覽器內的按鍵,它可以在后台與服務器進行悄悄的通信,從而可以驗證你的用戶名是否合法,你的郵箱是否存在等等關鍵性信息。

    2.0時代是講求效率的時代,AJAX的出現結合同步機制,在不同場景中因地制宜,達到快速有效的解決用戶數據交互問題,在學這個小技術的時候我更多的體會到了,設計這個技術的思維方式。

  • 離不開的關鍵性協議:HTTP


    超文本傳輸協議(HTTP,HigherText Transfer Protocol)我理解為一種通信協議。從我以前寫socket的經驗和計算機網絡的TCP協議來看,它其實是TCP協議的一種變式。“它是一種無狀態無連接的協議”。實際上它通信結束就馬上cut掉連接了,它的底層仍然是socket類似的通信,而且連接是基於TCP協議。

    說起HTTP,它不僅僅是只在B/S模型中應用廣泛,雖然很多應用都是一個空的瀏覽器嵌入前端代碼使用HTTP協議通信的,但在我看來它們也算是一種C/S模型。而HTTP協議的通信分為請求和響應兩部分。

    HTTP請求分為:請求行、消息頭、請求體。我們使用HTTP訪問服務器的時候,仍然是如socket一樣采用http://IPAddr:Port這樣的方式請求服務器。在建立連接后,瀏覽器發送請求行,瀏覽器發送請求頭;這時候服務器會做出應答,發送響應信息和狀態碼,服務器發送響應頭,服務器往瀏覽器發送數據,最后Web服務器關閉TCP連接。

    HTTP響應信息:狀態碼,響應頭,響應主體。狀態碼網上很多記錄,主要是記得200,404,500,這些特殊的。

                             

    我們可以使用chrome瀏覽器來觀察HTTP的請求和響應。請求頭一般包括文本類型,編碼方式,日期等。不做深入討論。

          

    有意思的是,html這個語言也主要分為head和body。這樣的設計讓我對HTTP這個協議加深了印象。

    HTTP請求方法有5個,在WEB開發中最主要的還是GET和POST。在展開之前根據需求先大體總結一下,GET請求是請求少量信息的方法,有信息量上限。POST的請求是對大量數據交互的方法。

    GET請求通常會把信息跟在url后面。GET請求沒有請求體。比如下圖。

    

    POST請求是把數據放在請求體內發送。

    

    在開發中需要謹記請求和響應這兩個關鍵過程。

  • 原生JavaScript的AJAX


    由於長期寫的都是后端語言,對這門函數式編程語言JavaScript生理上十分不適應。不過還好,我只需要熟悉怎么寫它的Ajax就好了。它的過程十分簡單。

    首先,獲取XHR對象,它被內嵌在瀏覽器中了,主要為了區別IE6這類特殊瀏覽器,不然直接調用XMLHttpRequest這個方法即可獲取。

    成功獲取對象之后使用open()方法傳入請求方法,請求url。這個onreadystatechange是一個回調函數,負責接收服務器響應數據的處理,這里類似將它重寫,瀏覽器會調用這個方法處理返回數據。

    send方法在GET請求中只需要傳入null,因為send方法是把數據放在請求體內,只有POST方式才會往send里寫數據。

    回調函數的寫法是按照模范代碼抄寫的。在responseText可以獲得服務端寫來的數據。

var XHR=false;
function createXHR(){
     if(window.XMLHttpRequest){
        XHR=new XMLHttpRequest();
    }else{
        XHR=new ActiveXObject("Microsoft.XMLHTTP");
    }
}
function checkUsername(){
    var username=document.getElementById("check").value;
    createXHR();
    XHR.open("get","checkUsername?username="+username,true);
    XHR.onreadystatechange=showMsgCallback;
    XHR.setRequestHeader("Content-type","application/x-www-form-urlencoded");  
    XHR.send();
}
function showMsgCallback(){
    if(XHR.readyState==4){
        if(XHR.status==200){
            var text=XHR.responseText.toString();  
            alert(text=='no');
            console.log(text);
            if(text=="yes"){
                 alert(1);
                document.getElementById("msg").innerHTML="此用戶名已注冊!";
            }
            else if(text=="no")
            {
                 alert(2);
                document.getElementById("msg").innerHTML="此用戶可以注冊";
            }
        }
    }
}

  

    配置Action的時候,我是將這個虛擬路徑映射到checkUsername()方法上。后端要獲得Ajax的數據,需要獲得reques對象,寫數據需要使用response對象。這就是為什么需要謹記請求和響應這兩個過程。

import java.io.IOException;
import java.io.PrintWriter;

import javax.management.relation.RoleUnresolved;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.SystemUtils;
import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;


public class CheckAction extends ActionSupport{
	private String name;
	
	public String getUsername() {
		return name;
	}

	public void setUsername(String name) {
		this.name = name;
	}

	public void checkUsername() {
		HttpServletRequest request = ServletActionContext.getRequest();
		name = request.getParameter("name");
		System.out.println(name);
		HttpServletResponse response = ServletActionContext.getResponse();
		response.setContentType("text/html");
		response.setCharacterEncoding("utf-8");
		PrintWriter out = null;
		try {
			out = response.getWriter();
		} catch (IOException e) {
			e.printStackTrace();
		}
		if (name.equals("ctk")) {
			out.print("no");
			out.flush();

		} else {
			out.print("yes");
			out.flush();
		}
		out.close();

	}

	public String execute(){
		
		return SUCCESS;
	}

}
  • Jquery是個什么鬼

    我本人對這種帶$和#的語言表示生理上十分不適應。雖然它很簡單。Jquery是一個封裝javascript的框架。它的目的是make js easier。Jquery的核心就是一個選擇器。它張這樣---$()。你在html上定義的id可以通過#來鎖定。什么class,css這些東西我都不想理了,太卵煩了。它的代碼讓人感覺很清爽,清爽得讓我看不懂。

 

	$(document).ready(function() {
		$('#button1').click(function() {
			var text = $('#msg1');
			$.ajax({
				type : "POST",
				url : "jquery",
				data : "username=ssss",
				dataType : 'text',
				success : function(result) {
					
					if (result=="success") {					
						text.text("");
						text.append("成功");
					}else{
						text.text("");
						text.append("失敗");
					}
				},
				error : function() {
					text.text("");
					text.append("操作出錯");
				}

			});
		});
	});
	$(document).ready(function(){
	    $('#button2').click(function(){
	        var text = $('#msg2');
	        $.post('jquery', 'username=xxxx',function(result){
	            if (result==="success") {					
						text.text("成功");
					}else{
						text.text("失敗");
					}
	        },'text');
	    });
	});
	$(document).ready(function(){
	    $('#button3').click(function(){
	        var text = $('#msg3');
	        $.get('jquery','username=zzzzz',function(result){
	            if (result==="success") {					
						text.text("成功");
					}else{
						text.text("失敗");
					}
	        });
	    });
	});

 

      這是我寫的三種Jquery的ajax寫法。它帶着html是長這樣。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>ajax交互</title>
<script src="jquery.min.js" type="text/javascript"></script>
<script type="text/javascript">

	$(document).ready(function() {
		$('#button1').click(function() {
			var text = $('#msg1');
			$.ajax({
				type : "POST",
				url : "jquery",
				data : "username=ssss",
				dataType : 'text',
				success : function(result) {
					
					if (result=="success") {					
						text.text("");
						text.append("成功");
					}else{
						text.text("");
						text.append("失敗");
					}
				},
				error : function() {
					text.text("");
					text.append("操作出錯");
				}

			});
		});
	});
	$(document).ready(function(){
	    $('#button2').click(function(){
	        var text = $('#msg2');
	        $.post('jquery', 'username=xxxx',function(result){
	            if (result==="success") {					
						text.text("成功");
					}else{
						text.text("失敗");
					}
	        },'text');
	    });
	});
	$(document).ready(function(){
	    $('#button3').click(function(){
	        var text = $('#msg3');
	        $.get('jquery','username=zzzzz',function(result){
	            if (result==="success") {					
						text.text("成功");
					}else{
						text.text("失敗");
					}
	        });
	    });
	});

</script>
</head>

<body>
	<button id="button1">點擊使用$ajax發送</button>
	<span id="msg1"></span>
	<br/>
	<button id="button2">點擊使用$post發送</button>
	<span id="msg2"></span>
	<br/>
	<button id="button3">點擊使用$get發送</button>
	<span id="msg3"></span>
	<br/>
</body>
</html>

    然后我在網上搜集到的這三種api的圖解。

    剛開始寫的時候有些不適應,最后感覺看着api,這種設計模式挺輕松的。

 

package servlet;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/jquery")
public class JqueryServlet extends HttpServlet{
    public JqueryServlet() {
        super();
        // TODO Auto-generated constructor stub
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String username=request.getParameter("username");
        System.out.println(username);
        response.setContentType("text/html");
        response.setCharacterEncoding("utf-8");
        PrintWriter out=response.getWriter();
        out.print("success");
        out.flush();
        out.close();
        
    }
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        doGet(request, response);
    }
}

    每次寫jquery的時候記得要導入jquery的源碼。

  • AJAX請求Struts2的Action

    起初我一直很疑惑,如何請求Action,那時因為對HTTP協議的理解不太深入。謹記請求和響應之后,AJAX的請求不過就是一個HTTP的請求,只要把請求路徑和Action名字對應,一切豁然開朗。

    

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%@ taglib prefix="s" uri="/struts-tags" %>
<%@ taglib prefix="sx" uri="/struts-dojo-tags" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>AJAX范例</title>
<sx:head/>
<script src="jquery.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function(){
    $('#usrname').blur(function(){
        $.ajax({
            type : "POST",
            url : "checkUsername",
            data : 'name='+$('#usrname').val(),
            dataType : 'text',
            success:function(data){
                if(data==='yes')
                    $('#msg').text('可以登錄');
                else if(data==='no')
                    $('#msg').text('無法登錄');
            }
        });
    });
});
</script>
</head>
<body>
<center>
    <form action="">
            <span id="msg"></span><br/>
        用戶名:<input id="usrname" name="name" type="text"/>
        <br/>
        密碼:<input name="password" type="password"/>
        <br/>
        <button type="submit">提交</button>
        <button type="reset">重置</button>
    </form>
</center>
</body>
</html>
package ActionPackage;

import java.io.IOException;
import java.io.PrintWriter;

import javax.management.relation.RoleUnresolved;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.SystemUtils;
import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;


public class CheckAction extends ActionSupport{
    private String name;
    
    public String getUsername() {
        return name;
    }

    public void setUsername(String name) {
        this.name = name;
    }

    public void checkUsername() {
        HttpServletRequest request = ServletActionContext.getRequest();
        name = request.getParameter("name");
        System.out.println(name);
        HttpServletResponse response = ServletActionContext.getResponse();
        response.setContentType("text/html");
        response.setCharacterEncoding("utf-8");
        PrintWriter out = null;
        try {
            out = response.getWriter();
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (name.equals("ctk")) {
            out.print("no");
            out.flush();

        } else {
            out.print("yes");
            out.flush();
        }
        out.close();

    }

    public String execute(){
        
        return SUCCESS;
    }

}
        <action name="checkUsername" class="ActionPackage.CheckAction" method="checkUsername">
        </action>
  • 后記

    首先我覺得書上寫不清楚,網上的也是很雜,不過摸着石頭過河的感覺還是很不錯的。學了一些前端的知識,寫了寫前端的代碼,也長了一些知識。附帶一個jquery的動畫。html有個失去焦點事件和點擊事件,都是設計所必要的。對當代網頁架構都有了新的認識,前后端分離的感覺挺fashion的。不積跬步無以至千里。

    

<html>
    
    <head>
        <title>this is a test page</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <script src="jquery.min.js" type="text/javascript"></script>
        <script src="jq.js" type="text/javascript"></script>
        
    </head>

    <body> 
        <div>
            <p>
                1.click me!
            </p>
            <p>
                2.click me!
            </p>
        </div>
        <button id="in">點擊淡入 div 元素。</button>
        <button id="out">點擊淡出 div 元素。</button>
        <div id="div1" style="width:80px;height:80px;display:none;background-color:red;"></div><br>
        <div id="div2" style="width:80px;height:80px;display:none;background-color:green;"></div><br>
        <div id="div3" style="width:80px;height:80px;display:none;background-color:blue;"></div>
    </body>
</html>




$(document).ready(function(){
   $("p").click(function(){
       $(this).hide();
   }) ;
});
$(document).ready(function(){
  $("#in").click(function(){
    $("#div1").fadeIn();
    $("#div2").fadeIn("slow");
    $("#div3").fadeIn(3000);
  });
});
$(document).ready(function(){
    $("#out").click(function(){
        $("#div1").fadeOut();
        $("#div2").fadeOut("slow");
        $("#div3").fadeOut(3000);
    });
});

 

    Ajax還有個load方法,請求載入內容的。

$(document).ready(function(){
    $('#ajaxrequest').click(function(){
        $('#directory').load('hello.html');
        alert('loaded');
    });
    
});

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM