AJAX - Asynchronous JavaScript and XML(异步的JavaScript 和 XML)。
AJAX 不是新的编程语言,而是一种使用现有标准的新方法
AJAX 是与服务器交换数据并更新部分网页的技术,在不重新加载整个网页的情况下。
大家都知道AJAX并非一种新的技术,而是几种原有技术的结合体,它由下列技术组合而成。
AJAX的核心是 XMLHttpRequest 对象。
不同的浏览器创建 XMLHttpRequest 对象的方法是有差异的。
IE浏览器使用 ActiveXObject ,而其他的浏览器使用名为 XMLHttpRequest 的 JavaScript 内建对象
AJAX的工作原理相当于在用户和服务器之间加了一个中间层(AJAX引擎),使用户操作与服务器响应异步化。并不是所有的用户请求都提交给服务器。像一些数据验证和数据处理等都交给AJAX引擎自己来做。只有确定需要从服务器获取新数据时再有AJAX引擎代为向服务器提交请求。
AJAX和传统方式的区别
传统的Web应用模型
用户点击或触发接口,通过Http协议发送相应请求给服务器,服务器处理,通过Http协议发送响应内容回客户端
AJAX模型
客户端用户点击或触发接口,通过JavaScript调用AJAX引擎,如果请求不需要更新数据,由AJAX代为完成,之后再返回响应给用户,如果请求需要更新数据或其他操作,那么就由AJAX再通过HTTP协议代为发送请求给服务器,服务器处理请求后响应到AJAX,AJAX再响应到服务器。
来看看他们个各自的交互方式:
浏览器的普通交互方式:
浏览器的AJAX交互方式:
在创建Web站点时,在客户端执行屏幕更新为用户提供了很大的灵活性。下面是使用AJAX可以完成的功能:
onreadystatechange属性存有处理服务器响应的函数。
下面的代码定义一个空的函数,可同时对 onreadystatechange 属性进行设置:
xmlHttp.onreadystatechange = function(){
//我们需要在这里写一些代码
}
readyState属性存有服务器响应的状态信息。每当readyState 改变时,onreadystatechange 函数就会被执行。
readyState 属性可能的值:
状态 | 描述 |
---|---|
0 | 请求未初始化(在调用open()之前) |
1 | 请求已提出(在调用send()之前) |
2 | 请求已发送(这里通常可以从响应得到内容头部) |
3 | 请求处理中(响应中通常有部分数据可用,但是服务器还没有完成响应) |
4 | 请求已完成(可以访问服务器响应并使用它) |
我们要向这个onreadystatechange函数添加一条if语句,来测试我们的响应是否已经完成(意味着可获得数据):
xmlHttp.onreadystatechange = function(){
if(xmlHttp.readyState == 4){
//请求处理完毕,可以获取response数据
}
}
可以通过responseText属性来取回由服务器返回的数据。
在我们的代码中,我们将在提示span标签内显示responseText。
xmlHttp.onreadystatechange = function(){
if(xmlHttp.readyState == 4){
document.getElementById("tip").innerHTML=xmlHttp.responseText
}
}
其他属性如下
属性名 | 描述 |
---|---|
onreadystatechange | 状态改变的事件触发器,每个状态改变时都会触发这个事件触发器,通常会调用一个JavaScript函数 |
readyState | 请求的状态 0-未初始化 1-正在加载 2-已加载 3-交互中 4-完成 |
responseText | 服务器的响应,返回数据的文本 |
responseXML | 服务器的响应,返回数据的兼容DOM的XML文档对象,这个对象可以解析为一个DOM对象 |
responseBody | 服务器返回的主题(非文本格式) |
responseStream | 服务器返回的数据流 |
status | 服务器的Http状态码(如404,200) |
statusText | 服务器返回的状态文本信息,Http状态码对应文本-“OK”、"Not Found"等等 |
open()有三个参数。第一个参数定义发送请求所使用的方法,第二个参数规定服务器端脚本的URL,第三个参数规定当对请求进行异步的处理。
xmlHttp.open("get","test.php",true);
send()方法将请求发送往服务器。里面的参数如果open设置了get的话,就是null,如果是post或put的话,就可以填写需要传递的参数。
如果我们假设HTML文件和PHP文件位于相同的目录,且get提交,那么代码是这样的
xmlHttp.open("get","xxx.php",true)
xmlHttp.send(null);
其他方法如下;
方法 | 描述 |
---|---|
abort() | 停止当前请求 |
getAllResponseHeaders() | 把HTTP请求的所有响应首部作为键/值对返回 |
getResponseHeader(“header”) | 返回指定首部的串值 |
open(“method”,“URL”,[asyncFlag],[“userName”],[“passWord”]) | 建立对服务器的调用,method参数可以是get,post或put,url参数可以是相对url或绝对url,这个方法还包括3个可选的参数,是否异步,用户名,密码 |
send(content) | 向服务器发送请求 |
setRequestHeader(“header”,“value”) | 把指定首部设置为所提供的值。在设置任何首部之前必须先调用open(),设置header并和请求一起发送(‘post’方法一定要) |
AJAX编程流程:
下面来看具体步骤
创建XMLHttp对象的语法是:
var xmlHttp = new XMLHttpRequest();
如果是IE5或IE6浏览器,则使用ActiveX对象,创建方法是:
var xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
一般我们手写AJAX的时候,首先需要判断浏览器是否支持XMLHttpRequest对象,如果支持则创建该对象,如果不支持则创建ActiveX对象。JS代码如下:
//第一步:创建XMLHttpRequest对象
var xmlHttp;
if(window.XMLHttpRequest){
//非IE
xmlHttp = new XMLHttpRequest();
}else if(window.ActiveXObject){
//IE
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
在WEB开发中,请求有两种形式,一个是get,一个是post,所以在这里需要设置以下具有使用哪个请求,XMLHttpRequest对象的open()方法就是用来设置请求方式的。
open()方法
功能 | 参数 |
---|---|
规定请求的类型、URL以及是否异步处理请求 | 参数1:设置请求类型(GET或POST)参数2:文件在服务器上的位置;参数3:是否异步处理请求,是为true,否为false |
如下:
//第二步:设置和服务器端交互的相应参数,向路径http://localhost:8080/JsLearning3/getAjax准备发送数据
varurl="http://localhost:8080/JsLearning3/getAjax";
xmlHttp.open("POST", url, true);
Get还是Post?
与post相比,get更简单也更快,并且在大部分情况下都能使用,然而,在以下情况中,请使用post请求:
异步true还是同步false?
AJAX指的是异步JavaScript和XML。XMLHttpRequest对象如果要用与AJAX的话,其open()方法的aync参数必须设置为true;对于web开发人员来说,发送异步请求是一个巨大的进步。很多在服务器执行的任务都相当费时。AJAX出现之前,这可能会引起应用程序挂起或停止。
通过AJAX,JavaScript无需等待服务器的响应,而是:
在等待服务器响应时执行其他脚本
当响应就绪后就对响应进行处理
如果在上一步中open方法的第三个参数选择的是true,那么当前就是异步请求,这个时候需要写一个回调函数,XMLHttpRequest对象有一个onreadystatechange属性,这个属性返回的是一个匿名方法,所以回调函数 就在这里写。所谓回调函数,定义就是请求在后台处理完,如何处理服务器返回的响应,如何发往前台的函数。在这个例子里,我们的回调函数主要实现的功能就是接收后台响应回来的字符串然后发往前台显示到指定div上,因为从后台返回的数据可能是错误的,所以在回调函数中首先要判断后台返回的信息是否正确,如果正确才可以继续执行。代码如下:
//第三步:编写回调函数
xmlHttp.onreadystatechange = function(){
if(xmlHttp.readyState == 4){
if(xmlHttp.status == 200){
var obj = document.getElementById(id);
obj.innerHTML = xmlHttp.responseText;
}else{
alert("AJAX服务器返回错误!")
}
}
}
在上面代码中,xmlHttp.readyState是存有XMLHttpRequest的状态。从0到4发生变化
xmlHttp.status是服务器返回的结果。其中200代表正确
var obj = document.getElementById(id);
obj.innerHTML = xmlHttp.responseText;
这段代码是回调函数的核心内容。就是获取后台返回的数据,然后将这个数据赋值给对应的div,xmlHttp对象有两个属性都可以获取后台返回的数据,分别是:responseText和responseXML,其中responseText是用来获取字符串形式的响应数据,responseXML是用来获取XML形式的响应数据。至于选择哪一个取决于后台返回的数据。这个例子我们只是显示一条字符串数据所以选择的是responseText。responseXML将会在以后的例子中介绍。
AJAX状态码说明:
1:请求收到,继续处理
2:操作成功收到,分析、接受
3:完成此请求必须进一步处理
4:请求包含一个错误语法或不能完成
5:服务器执行一个完全有效请求失败
再具体就如下:
100——客户必须继续发出请求
101——客户要求服务器根据请求转换HTTP协议版本
200——交易成功
201——提示知道新文件的URL
202——接受和处理、但处理未完成
203——返回信息不确定或不完整
204——请求收到,但返回信息为空
205——服务器完成了请求,用户代理必须复位当前已经浏览过的文件
206——服务器已经完成了部分用户的GET请求
300——请求的资源可在多处得到
301——删除请求数据
302——在其他地址发现了请求数据
303——建议客户访问其他URL或访问方式
304——客户端已经执行了GET,但文件未变化
305——请求的资源必须从服务器指定的地址得到
306——前一版本HTTP中使用的代码,现行版本中不再使用
307——申明请求的资源临时性删除
400——错误请求,如语法错误
401——请求授权失败
402——保留有效ChargeTo头响应
403——请求不允许
404——没有发现文件、查询或URl
405——用户在Request-Line字段定义的方法不允许
406——根据用户发送的Accept拖,请求资源不可访问
407——类似401,用户必须首先在代理服务器上得到授权
408——客户端没有在用户指定的饿时间内完成请求
409——对当前资源状态,请求不能完成
410——服务器上不再有此资源且无进一步的参考地址
411——服务器拒绝用户定义的Content-Length属性请求
412——一个或多个请求头字段在当前请求中错误
413——请求的资源大于服务器允许的大小
414——请求的资源URL⻓于服务器允许的⻓度
415——请求资源不支持请求项目格式
416——请求中包含Range请求头字段,在当前请求资源范围内没有range指示值,请求也不包含If-Range请求头字段
417——服务器不满足请求Expect头字段指定的期望值,如果是代理服务器,可能是下一级服务器不能满足请求
500——服务器产生内部错误
501——服务器不支持请求的函数
502——服务器暂时不可用,有时是为了防止发生系统过载
503——服务器过载或暂停维修
504——关口过载,服务器使用另一个关口或服务来响应用户,等待时间设定值较⻓
505——服务器不支持或拒绝支请求头中指定的HTTP版本
//第四部:设置发送请求的内容然后发送请求
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded;charset=UTF-8");
xmlhttp.send("username="+username);
如果需要像HTML表单那样post数据,请使用setRequestHeader()来添加http头,然后在send()方法中规定想要添加的数据。
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$title>
head>
<body>
<h1>index.jsph1>
username:<input type="text" id="username" onblur="test()"><span id="rs">span>
body>
html>
<script type="text/javascript">
function test() {
//发送异步请求
//1.创建XMLHttpRequest对象
var xmlhttp;
if(window.XMLHttpRequest){
//非IE
xmlhttp = new XMLHttpRequest();
}else if(window.ActiveXObject){
//IE
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
//2.打开连接
var username = document.getElementById("username").value;
//get
//xmlhttp.open("get","/testuname?username="+username,true);
//post
xmlhttp.open("post","/testuname",true);
//3.指定回调函数
xmlhttp.onreadystatechange = function (){
//3.1 判断状态
if(xmlhttp.readyState==4){
//3.2接收返回的数据
var responseText = xmlhttp.responseText;
document.getElementById("rs").innerHTML = responseText;
}
}
//4.发送请求
//get
//xmlhttp.send(null);
//post,必须设置请求头信息
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded;charset=UTF-8");
xmlhttp.send("username="+username);
};
script>
servlet:
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet(
urlPatterns = "/testuname"
)
public class TestServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String username = req.getParameter("username");
resp.setContentType("text/html;charset=utf-8");
PrintWriter writer = resp.getWriter();
if("admin".equals(username)){
writer.println("账户已被注册");
}else {
writer.println("账户可用");
}
}
}
步骤繁琐,代码量多,属性,常用值太多不好记忆。
可以通过发送HTTP请求加载远程数据,是JQuery最底层的Ajax实现,具有较高灵活性。
$.ajax([settings]);
settings是$.ajax()方法的参数列表,用于配置AJAX请求的键值对集合;
$.ajax({
url:"请求地址",
type:"提交方法,默认get"
data:"请求携带的参数,{"id":"123","pwd":"123456"}",
dataType:"请求参数数据类型,如html,text,json,xml,script.jsonp",
success:function(data,dataTextStatus,jqxhr){}//请求成功的回调函数
error:function(jqxhr,textStatus,error){}//但凡发生异常都会调用的回调函数
});
这是一个简单的GET请求功能以取代复杂的$.ajax。
$.get(url,data,function(result){
//回调函数
});
$.post(url,data,function(result){
//回调函数
});
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于阅读和编写。同时也易于机器解析和生成。JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯。这些特征使得JSON称为理想的数据交换语言。
在标准的JSON格式中,JSON对象由大扩大括起来,对象中的属性也就是JSON的KEY是一个字符串,所以一定要使用双印号引起来,每组key之间使用逗号进行分割。
var 变量名 = {
"key1":value,//Number类型
"key2":"value"//字符串类型
"key3":[],//数组类型
"key4":{},//json对象类型
"key5":[{},{}],//json对象数组
};
JSON对象,顾名思义,就知道它是一个对象。里面的key就是对象的属性。我们要访问一个对象的属性,只需要使用 对象.属性
的方式访问即可。
//json的定义
var jsons = {
"key1":"abc",//字符串
"key2":1234,//number
"key3":[1234,"abcd"],//数组
"key4":{
"keyA":12,
"keyB":"abc"
},//Json类型
"key5":[{
"key_1":123,
"key_2":"abc"
},{
"key_3":456,
"key_4":"abc"
}]//json对象数组
};
//访问json的属性
alert(jsons.key1);//abc
//访问json的数组属性
alert(jsons.key3[1]);//abcd
//访问json的json属性
alert(jsons.key4.keyA);//12
//访问json的json数组
alert(jsons.key5[0].key_2);//abc
我们想要在java中使用json,我们需要使用到一个第三方jar包:
Users user = new Users(1,"李四","18");
JSONObject json = JSONObject.fromObject(user);//json就是JSON格式的
String str = "{'username':'李四','password':'admin','age':19}";
//将字符串转换成JSON类型
JSONObject json = JSONObject.fromObject(str);
Users user = JSONObject.toBean(json,User.class);
ArrayList list = new ArrayList();
list.add("a");
list.add("b");
JSONArray json = JSONArray.fromObject(list);//set也是这么转
方式一:
String str = "[{'age':20,'password':'123'},{'age':30,'password':'12345'}]";
JSONArray json = JSONArray.fromObject(str);
Object[] os = (Object[])JSONArray.toArray(json,Users.class);
方式二:
String str = "[{'age':20,'password':'123'},{'age':30,'password':'12345'}]";
JSONArray json = JSONArray.fromObject(str);
List<Users> list = JSONArray.toCollection(json,Users.class);
页面:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Titletitle>
<script type="text/javascript" src="js/jquery-1.11.1.js">script>
head>
<body>
uid:<input type="text" id="uid"><br>
name:<input type="text" id="uname"><br>
pass:<input type="text" id="upass"><br>
money:<input type="text" id="money">
body>
html>
<script type="text/javascript">
$(function () {
$("#uid").blur(function () {
//获取uid
var uid = $(this).val();
//JQueryAJAX
$.post("/usertest","uid="+uid,function (ujson) {
//将返回值转换成可以处理的json
ujson=eval("("+ujson+")");
//此时的ujson是json格式的对象
$("#uname").val(ujson.username);
$("#upass").val(ujson.password);
$("#money").val(ujson.money);
});
})
});
script>
后台:
实体类:
public class Users {
private Integer uid;
private String username;
private String password;
private String money;
}
处理类:
import bean.Users;
import net.sf.json.JSONObject;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet(
urlPatterns = "/usertest"
)
public class UserServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Users users = null;
int uid = Integer.parseInt(req.getParameter("uid"));
switch (uid){
case 1:
users = new Users(1,"张三","123456","700");
break;
case 2:
users = new Users(2,"李四","123456","8100");
break;
case 3:
users = new Users(3,"周九","123456","7500");
break;
case 4:
users = new Users(4,"王八","123456","20000");
break;
default:
users = new Users();
break;
}
//java->json
//发送给前台
resp.setContentType("text/html;charset=utf-8");
JSONObject jsonObject = JSONObject.fromObject(users);
PrintWriter writer = resp.getWriter();
writer.print(jsonObject);
}
}