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="80px;height:80px;display:none;background-color:red;"></div><br>
        <div id="div2" style="80px;height:80px;display:none;background-color:green;"></div><br>
        <div id="div3" style="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');
    });
    
});
原文地址:https://www.cnblogs.com/chentingk/p/5763153.html