Ajax学习日记1
什么是Ajax
Ajax = 异步 JavaScript 和 XML。
Ajax 是一种用于创建快速动态网页的技术。是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。
通过在后台与服务器进行少量数据交换,Ajax 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。
传统的网页(不使用 Ajax)如果需要更新内容,必需重载整个网页面。
Ajax在很多地方应用,以下就是Ajax的一种使用
Ajax的由来
2005 年Jesse James Garrett 发表了一篇文章,标题为:“Ajax:A new Approach to Web Applications”。他在这篇文章里介绍了一种技术。用他的话说,就叫:Ajax,是Asynchronous JavaScript + XML 的简写。
使用Ajax的好处
- 能够向服务器请求额外的数据而无须卸载页面(即刷新);
- Ajax使用异步方式与服务器通信,不需要打断用户的操作,会带来更好的用户体验。
- 基于标准被广泛支持。
Ajax的使用
Ajax 技术核心是XMLHttpRequest对象(简称XHR)——这是由微软首先引入的一个特性。
XHR 的出现,提供了向服务器发送请求和解析服务器响应提供了流畅的接口。能够以异步方式从服务器获取更多的信息,这就意味着,用户只要触发某一事件,在不刷新网页的情况下,更新服务器最新的数据。
注意:
虽然Ajax 中的x 代表的是XML,但Ajax 通信和数据格式无关,也就
是说这种技术不一定使用XML。
IE7+、Firefox、Opera、Chrome 和Safari 都支持原生的XHR 对象,
在这些浏览器中创建XHR 对象可以直接实例化XMLHttpRequest 即可。
var xhr = new XMLHttpRequest();
alert(xhr); //XMLHttpRequest
如果是IE6 及以下,那么我们必须还需要使用ActiveX 对象通过
MSXML 库来实现。
发送请求
在使用XHR 对象时,先必须调用open()方法,它接受三个参数:要发送的请求类型(get、post)、请求的URL 和表示是否异步。
xhr.open(‘get’, ‘demo.jsp’, false);
//对于demo.jsp 的get 请求,false 同步,true异步;
open()方法并不会真正发送请求,而只是启动一个请求以备发送。
通过send()方法进行发送请求,send()方法接受一个参数,作为请求主体发送的数据。如果不需要则,必须填null。
执行send()方法之后,请求就会发送到服务器上。
xhr.send(null); //发送请求
当请求发送到服务器端,收到响应后,响应的数据会自动填充XHR
对象的属性。那么一共有四个属性:
属性名 | 说明 |
---|---|
responseText | 作为响应主体被返回的文本 |
responseXML | 如果响应主体内容类型是“text/xml”或“application/xml”,则返回包含响应数据的XML DOM文档 |
status | 响应的HTTP状态 |
statusText | HTTP状态的说明 |
IE浏览器有个特点,它第一次会向服务器发送请求,获取最新数据,而第二次它就默认默认取缓存的数据,导致数据不更新!那怎么处理呢?可以使用js的随机数来解决!
'server.jsp?rand='+Math.random()
接受响应
接受响应之后,第一步检查status 属性,以确定响应已经成功返回。一般而已HTTP 状态代码为200 作为成功的标志。除了成功的状态代码,还有一些别的:
HTTP状态码 | 状态字符串 | 说明 |
---|---|---|
200 | OK | 服务器成功返回了页面 |
400 | Bad Request | 语法错误导致服务器不识别 |
401 | Unauthorized | 请求需要用户认证 |
404 | Not found | 指定的URL在服务器上找不到 |
500 | Internal ServerError | 服务器遇到意外错误,无法完成请求 |
503 | ServiceUnavailable | 由于服务器过载或维护导致无法完成请求 |
使用异步调用的时候,需要触发xhr.onreadystatechange 事件,然后检测readyState 属性即可。这个属性有五个值:
值 | 状态 | 说明 |
---|---|---|
0 | 未初始化 | 尚未调用open()方法 |
1 | 启动 | 已经调用open()方法,但尚未调用send()方法 |
2 | 发送 | 已经调用send()方法,但尚未接受响应 |
3 | 接受 | 已经接受到部分响应数据 |
4 | 完成 | 已经接受到全部响应数据,而且可以使用 |
xhr.responseText; //返回数据传输的值
GET与 POST
GET 请求是最常见的请求类型,最常用于向服务器查询某些信息。必要时,可以将查询字符串参数追加到URL 的末尾,以便提交给服务器。
xhr.open('get', 'demo.php?rand=' + Math.random() + '&name=Koo', true);
而发送POST 请求的数据,不会跟在URL 的尾巴上,而是通过send()方法向服务器提交数据。
xhr.send('name=Lee&age=100');
一般来说,向服务器发送POST 请求由于解析机制的原因,需要进行特别的处理。因为POST 请求和Web 表单提交是不同的,需要使用XHR 来模仿表单提交。
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
Ajax的应用
简单的Ajax的应用
应用1:简单使用Ajax的方法
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<p id="ppp"></p>
<script type="text/javascript">
var xhr = new XMLHttpRequest();
alert(xhr);
xhr.open('get','/web07/ajaxTestServlet?name=jack',true); //open但是并没有真正向服务器发送请求
xhr.send(null); //get方式发送请求 这里需要填如null,post方式发送的时候 send("name=jack")
xhr.onreadystatechange=function(){
if(xhr.status==200){ //服务器的响应状态码
// 说明服务器正常相应了
if(xhr.readyState==4){ //ajax的状态码
var d=xhr.responseText;
ppp.innerHTML=d;
}
}
}
}
</script>
</body>
</html>
再新建一个java文件
public class AjaxTestServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String name=req.getParameter("name");
PrintWriter writer = resp.getWriter();
writer.write("name:"+name);//输出
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
记得要在web.xml中更改配置
<servlet>
<servlet-name>ajaxTestServlet</servlet-name>
<servlet-class>com.AjaxTestServlet.AjaxTestServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ajaxTestServlet</servlet-name>
<url-pattern>/ajaxTestServlet</url-pattern>
</servlet-mapping>
应用2:在页面输出当前时间戳
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<p id="ppp"></p>
<script type="text/javascript">
setInterval(function(){
ajaxFun();
},2)
function ajaxFun(){
var xhr = new XMLHttpRequest();
xhr.open('post','/web07/ajaxTestServlet',true); //post 请求 唯一的方式就是表单提交
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); //这行代码就使用在post方式提交 “骗”过服务器是以表单的方式提交过去的
xhr.send("name=rose");
xhr.onreadystatechange=function(){
if(xhr.status==200){ //服务器的响应状态码
// 说明服务器正常相应了
if(xhr.readyState==4){ //ajax的状态码
var d=xhr.responseText;
ppp.innerHTML=d;
}
}
}
}
</script>
</body>
</html>
在java文件中写
public class AjaxTestServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
PrintWriter writer = resp.getWriter();
writer.write(System.currentTimeMillis()+"");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
应用3:使用Ajax进行登录验证
首先的dao包中的客户类中定义验证方法(通过用户名查询是否有重复用户)
int getCountCustomerByName(String cu_name);
在它的实现类中实现它的验证方法
@Override
public int getCountCustomerByName(String cu_name) {
int count=0;
try {
//获取数据库连接
Connection conn = DBHelper.getConnection();
//编写sql命令
String sql="select count(*) from customer where cu_name=?";
List param = new ArrayList();
param.add(cu_name);
//执行命令返回资源结果集
ResultSet rs = DBHelper.executeQuery(conn, sql, param);
rs.next();
count=rs.getInt(1);
//关闭数据库
DBHelper.closeConnection(conn);
} catch(Exception e) {
e.printStackTrace();
}
return count;
}
在Controller包中的用户类中,接受输入并调用方法去完成需求
public int getCountCustomerByName(String cu_name) {
return customerDao.getCountCustomerByName(cu_name);
}
在Servlet包中去处理这些方法
public class CheckCustomerNameServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");
String cu_name = req.getParameter("cu_name");
System.out.println("cu_name->"+cu_name);
int c = new CustomerController().getCountCustomerByName(cu_name);
System.out.println(c);
PrintWriter writer = resp.getWriter();
writer.write(c+"");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
在web.xml中更改servlet配置
<servlet>
<servlet-name>checkCustomerNameServlet</servlet-name>
<servlet-class>com.ishopn.servlet.CheckCustomerNameServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>checkCustomerNameServlet</servlet-name>
<url-pattern>/checkCustomerNameServlet</url-pattern>
</servlet-mapping>
然后在注册界面添加事件去实现登录验证
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>注册界面</title>
</head>
<body>
<form action="/web06/insterCustomerServlet" method="post" onsubmit="return check()">
用户名称:<input type="text" name="cu_name" id="name1"/><br />
用户手机:<input type="text" name="cu_phone" /><br />
用户性别:
<select name="cu_gender">
<option value="1" selected>男</option>
<option value="0" >女</option>
</select>
用户地址:<input type="text" name="cu_address" /><br />
<input type="submit" value="注册" /> <a href="/web06">已经注册了?</a>
</form>
<script type="text/javascript" src="js/regist.js"></script>
</body>
</html>
用JavaScript实现以上触发事件。
var flag = true;
var inputs = document.getElementsByTagName("input");
function check(){
for(var i=0;i<inputs.length;i++){
if(inputs[i].value==null || inputs[i].value.trim().length==0){
flag = false;
alert("所有信息不能为空");
break;
}
}
return flag;
}
function chechName(){
}
name1.onblur=function(){
var t = this.value;
if(t.length>0){
var xhr = new XMLHttpRequest();
xhr.open('post','/web06/checkCustomerNameServlet',true);
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
xhr.send("cu_name="+t);
xhr.onreadystatechange=function(){
if(xhr.status==200){
if(xhr.readyState==4){
var c = xhr.responseText;
if(c>0){
alert("用户名已经存在");
flag = false;
}else{
flag = true;
}
}
}
}
}
}