一、ajax简介
- AJAX 即 “Asynchronous Javascript And XML”,是指一种创建交互式网页应用的网页开发技术。
- AJAX = 异步 JacaScript 和 XML(标准通用标记语言的子集)。
- AJAX不是一种新的编程语言,而是一种用于创建更好更快以及交互性更强的Web应用程序的技术。
- Ajax在无需重新加载整个页面的情况下,能够更新部分页面。
利用AJAX可以做:
- 注册时,输入用户名自动检测用户是否已经存在。
- 登陆时,提示用户名密码错误
- 删除数据行时,将行ID发送到后台,后台在数据库中删除,数据库删除成功后,在页面DOM中将数据行也删除。
二、ajax原理
通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。传统的网页(不使用 AJAX)如果需要更新内容,必须重载整个网页页面。
传统的交互:
发送一个请求,用户在浏览器中填写一些表单信息,点击发送请求到web服务器中,发送之后当前页面会被销毁掉,服务器端对表单信息进行检验然后返回一系列信息响应到浏览器(这里响应的是完整的页面)。如果用户的信息反复验证后仍不能通过,那么这期间就耗费了网络资源,并占用服务器资源。
Ajax:
Ajax通过在浏览器中添加XmlHttpRequest对象(该对象同时绑定一段事件处理函数)向服务器端发送异步请求,当用户点击提交信息时.调用Ajax此对象的方法来发送请求,这种方式并不会销毁页面。当服务器获取到数据后给到的响应是部分数据,而不再是完整的页面,当这部分数据到达客户端时不是由浏览器展示,而是由事件处理函数接收、解析,取出后,由JavaScript的代码控制这些数据及样式,然后更新至页面的某一个位置。
三、ajax应用
1、伪造ajax
- 所谓伪造AJAX,是指通过<iframe>标签局部加载内容的特性,来伪造 AJAX 请求,从而实现页面异步更新。
- iframe标签是框架的一种形式,一般用来包含别的页面,例如我们可以在我们自己的网站页面加载别人网站或者本站其他页面的内容。
代码实现:
注:myDate.getTime() 返回时间戳,在加载地址时时间戳不变,那证明页面局部刷新。
1 <!DOCTYPE html> 2 <html> 3 <head lang="en"> 4 <meta charset="UTF-8"> 5 <title>伪造AJAX</title> 6 </head> 7 <body> 8 <div> 9 <p>请输入要加载的地址:<span id="currentTime"></span></p> 10 <p> 11 <input id="url" type="text" /> 12 <input type="button" value="提交" onclick="LoadPage();"> 13 </p> 14 </div> 15 <div> 16 <h3>加载页面位置:</h3> 17 <iframe id="iframePosition" style="width: 100%;height: 500px;"></iframe> 18 </div> 19 <script type="text/javascript"> 20 window.onload= function(){ 21 var myDate = new Date(); 22 document.getElementById('currentTime').innerText = myDate.getTime(); 23 24 }; 25 function LoadPage(){ 26 var targetUrl = document.getElementById('url').value; 27 document.getElementById("iframePosition").src = targetUrl; 28 } 29 </script> 30 </body> 31 </html>
2、原生ajax
- Ajax的核心是XMLHttpRequest对象(XHR)。XHR为向服务器发送请求和解析服务器响应提供了接口。能够以异步方式从服务器获取新数据。
- 该对象在主流浏览器中均存在(除早起的IE),Ajax首次出现 IE5.5 中存在(ActiveX控件)。
(1)、获得ajax对象
Ajax对象本身是浏览器中的一个内置对象
- IE浏览器中是:ActiveXObject("Microsoft.XMLHTTP") (IE7之后开始支持XMLHttpRequest)
- 其它浏览器中是:XMLHttpRequest
- 可以根据浏览器差异创建不同的Ajax对象
if(window.XMLHttpRequest){
new XMLHttpRequest();
}else{
new ActiveXOBject("Microsoft.XMTHTTP");
}
(2)、ajax对象的属性和方法
ajax对象的主要方法:
a. void open(String method,String url,Boolen async)
用于创建请求
参数:
method: 请求方式(字符串类型),如:POST、GET、DELETE...
url: 要请求的地址(字符串类型)
async: 是否异步(布尔类型)
b. void send(String body)
用于发送请求
参数:
body: 要发送的数据(字符串类型)
c. void setRequestHeader(String header,String value)
用于设置请求头
参数:
header: 请求头的key(字符串类型)
vlaue: 请求头的value(字符串类型)
d. String getAllResponseHeaders()
获取所有响应头
返回值:
响应头数据(字符串类型)
e. String getResponseHeader(String header)
获取响应头中指定header的值
参数:
header: 响应头的key(字符串类型)
返回值:
响应头中指定的header对应的值
f. void abort()
终止请求
ajax的主要属性:
a. Number readyState
状态值(整数)
详细:
0-未初始化,尚未调用open()方法;
1-启动,调用了open()方法,未调用send()方法;
2-发送,已经调用了send()方法,未接收到响应;
3-接收,已经接收到部分响应数据;
4-完成,已经接收到全部响应数据;
b. Function onreadystatechange
当readyState的值改变时自动触发执行其对应的函数(回调函数)
c. String responseText
服务器返回的数据(字符串类型)
d. XmlDocument responseXML
服务器返回的数据(Xml对象)
e. Number states
状态码(整数),如:200、404...
f. String statesText
状态文本(字符串),如:OK、NotFound...
(3)、设置get与post请求响应
- onreadystatechange绑定一个事件处理函数,当readystate请求状态发生改变时被触发。
- 函数一般对readystate为4,status为200做处理,即保证接收数据是成功响应的数据。
发送get请求的基本步骤如下:
- 获取Ajax对象;获取XMLHttpRequest对象
- 创建请求:调用open()方法,设置Ajax对象发送请求前的必要数据.
- 设置回调函数:为Ajax对象的onreadystatechange事件设定相应函数
- 发送请求:调用Ajax的send()方法
get请求:
xhr.open(‘get’,URL,true);
- ‘get’,使用"get"即发送get请求
- URL,填写发送请求的地址,可以通过"?"的方式追加"name=value"对象。
- true表示请求是异步的,脚本执行send()方法后不等待服务器的执行结果,而是继续执行脚本代码。false表示是同步的,脚本执行send方法后等待服务器的响应,若等待超时,则不再等待,继续执行后面的脚本代码。
post请求:
- POST请求用于向服务器发送应该被保存的数据。
- POST请求的主体可以包含非常多的数据,而且格式不限。
- 缺少一个消息头信息,“content-type”,需要人为设置.
- 发送数据只能通过send(),不能在open()中url拼接’?’
代码实现:
RegistServlet.java
package ajax; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class RegistServlet extends HttpServlet { @Override protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // request接收浏览器请求的对象 // response服务器端返回响应的对象 // 服务器端解决乱码 //request.setCharacterEncoding("utf-8"); //response.setContentType("text/html;charset=utf-8"); // 接收请求参数 String username = request.getParameter("username"); // 获得响应流 PrintWriter out = response.getWriter(); // 做出响应 if (username.equals("gql")) { out.println("该用户名已注册"); } else { out.println("注册成功"); } out.close(); } }
regist.html
<!DOCTYPE html> <html> <head> <title>regist.html</title> <meta charset="utf-8" /> <script src="js/jQuery-3.4.1.js"></script> <script> $(function() { //get方式发送Ajax请求 $("#bt1").click(function() { //1.创建Ajax对象 var xhr; if (window.XMLHttpRequest) { //其他浏览器 xhr = new XMLHttpRequest(); } else { //IE浏览器 xhr = new ActiveXObject("Microsoft.XMLHTTP"); } //2.通过open()方法,设置Ajax对象发送请求前的必要数据 //获得用户名username的value值 var username = $("#username").val(); xhr.open('get', 'regist?username=' + username, true); //3.指定事件响应的方法 xhr.onreadystatechange = function() { if (xhr.readyState == 4 && xhr.status == 200) { //获得服务器响应的文本内容 var txt = xhr.responseText; alert(txt); } } //4.调用send()方法 xhr.send(null); }) //post方式发送Ajax请求 $("#bt2").click( function() { //1.创建Ajax对象 var xhr; if (window.XMLHttpRequest) { xhr = new XMLHttpRequest(); } else { xhr = new ActiveXObject("Microsoft.XMLHTTP"); } //2.通过open()方法,设置Ajax对象发送请求前的必要数据 xhr.open('post', 'regist', true); //post设置请求头 xhr.setRequestHeader("content-type", "application/x-www-form-urlencoded"); //3.指定事件响应方法 xhr.onreadystatechange = function() { if (xhr.readyState == 4 && xhr.status == 200) { var txt = xhr.responseText; $("#sp").text(txt); } } //4.调用spend()发送数据 xhr.send("username=" + $("#username").val()); }) }) </script> </head> <body> <form> 用户名: <input type="text" id="username" name="username" value="my" /><span id="sp"></span><br /> 密码: <input type="password" name="password"><br /> 简介: <textarea rows="5" cols="22"></textarea><br /> <input type="button" value="get方式注册" id="bt1" /><br /> <input type="button" value="post方式注册" id="bt2" /><br /> </form> </body> </html>
(4)、乱码问题
- 乱码产生的原因:客户端编码与服务端编码不一致。
解决get请求时的乱码问题
①、服务器端:
Tomcat可以修改conf/server.xml
文件第一行中
<Connector URLEncoding = "UTF-8">
服务器会按照utf-8解码,也可以按照post客户端解决方式
②、客户端:
xhr.open(‘get’,encodeURL(urI),true);
IE按照GBK编码,其他按utf-8,为了统一encodeURI可以设置浏览器按照utf-8编码。
解决post请求时的乱码问题
①服务器端
// 服务器端解决乱码
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
②客户端:所有浏览器post请求默认都是utf-8编码
3、jquery对ajax的支持
- 用法:
$.ajax({选项1:"",选项2:""})
- jQuery 既然是JavaScript的类库,那肯定也封装了AJAX使用相关方法,会使我们开发用起来更简单。
- jQuery Ajax的本质无疑是 XMLHttpRequest 或 ActiveXObject
jQuery Ajax 常用方法有三个:get、post、ajax:
# jQuery Ajax 方法列表
jQuery.get(...)
所有参数:
url: 待载入页面的URL地址
data: 待发送 Key/value 参数。
success: 载入成功时回调函数。
dataType: 返回内容格式,xml, json, script, text, html
jQuery.post(...)
所有参数:
url: 待载入页面的URL地址
data: 待发送 Key/value 参数
success: 载入成功时回调函数
dataType: 返回内容格式,xml, json, script, text, html
jQuery.getJSON(...)
所有参数:
url: 待载入页面的URL地址
data: 待发送 Key/value 参数。
success: 载入成功时回调函数。
jQuery.getScript(...)
所有参数:
url: 待载入页面的URL地址
data: 待发送 Key/value 参数。
success: 载入成功时回调函数。
jQuery.ajax(...)
部分参数:
url:请求地址
type:请求方式,GET、POST(1.9.0之后用method)
headers:请求头
data:要发送的数据
contentType:即将发送信息至服务器的内容编码类型(默认: "application/x-www-form-urlencoded; charset=UTF-8")
async:是否异步
timeout:设置请求超时时间(毫秒)
beforeSend:发送请求前执行的函数(全局)
complete:完成之后执行的回调函数(全局)
success:成功之后执行的回调函数(全局)
error:失败之后执行的回调函数(全局)
accepts:通过请求头发送给服务器,告诉服务器当前客户端课接受的数据类型
dataType:将服务器端返回的数据转换成指定类型
"xml": 将服务器端返回的内容转换成xml格式
"text": 将服务器端返回的内容转换成普通文本格式
"html": 将服务器端返回的内容转换成普通文本格式,在插入DOM中时,如果包含JavaScript标签,则会尝试去执行。
"script": 尝试将返回值当作JavaScript去执行,然后再将服务器端返回的内容转换成普通文本格式
"json": 将服务器端返回的内容转换成相应的JavaScript对象
"jsonp": JSONP 格式
使用 JSONP 形式调用函数时,如 "myurl?callback=?" jQuery 将自动替换 ? 为正确的函数名,以执行回调函数
如果不指定,jQuery 将自动根据HTTP包MIME信息返回相应类型(an XML MIME type will yield XML, in 1.4 JSON will yield a JavaScript object, in 1.4 script will execute the script, and anything else will be returned as a string
converters: 转换器,将服务器端的内容根据指定的dataType转换类型,并传值给success回调函数
$.ajax({
accepts: {
mycustomtype: 'application/x-some-custom-type'
},
// Expect a `mycustomtype` back from server
dataType: 'mycustomtype',
// Instructions for how to deserialize a `mycustomtype`
converters: {
'text mycustomtype': function(result) {
// Do Stuff
return newresult;
}
},
});
代码实现:
regist_jquery.htm:
<!DOCTYPE html> <html> <head> <title>regist_jquery.html</title> <meta charset="utf-8"/> <script src="js/jQuery-3.4.1.js"></script> <script type="text/javascript"> $(function(){ //用jQuery的方式发送Ajax请求 $("#bt1").click(function(){ //获取用户名和密码的值 var username = $("#username").val(); var password = $(":password").val(); $.ajax({ type:'get', url:"regist?username="+username+"&password="+password, async:true, success:function(data){ $("#sp").text(data); }, error:function(data){ alert("注册失败"); } }) }) }) </script> </head> <body> <form> 用户名: <input type="text" id="username" name="username" value="mary" /><span id="sp"></span><br /> 密码: <input type="password" name="password"><br /> 简介: <textarea rows="5" cols="22"></textarea><br /> <input type="button" id="bt1" value="get方式注册" /><br /> </form> </body> </html>
RegistServlet.java:
package ajax; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class RegistServlet extends HttpServlet { @Override protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // request接收浏览器请求的对象 // response服务器端返回响应的对象 // 服务器端解决乱码 request.setCharacterEncoding("utf-8"); response.setContentType("text/html;charset=utf-8"); // 接收请求参数 String username = request.getParameter("username"); String password = request.getParameter("password"); // 获得响应流 PrintWriter out = response.getWriter(); // 做出响应 if (username.equals("gql")) { out.println("该用户名已注册"); } else { out.println("注册成功"); } out.close(); } }
4、json支持ajax
Json(Javascript Object Notation,JS对象简谱)是一种轻量级的数据交换格式。
- Json转化为JavaScript
<!DOCTYPE html> <html> <head> <title>json.html</title> <script type="text/javascript"> function f1(){ //创建json串的字符串 var jn1 = '{"id":1,"name":"蝶","salary":7000}'; //json字符串-->js对象 var obj =JSON.parse(jn1); alert(obj.name); } function f2(){ //创建json数组 var jn2 ='[13,25,46]'; //json数组-->js数组 var obje1 =JSON.parse(jn2); alert(obje1[0]); } </script> </head> <body> <input type="button" value="json字符串-->js对象" onclick="f1()" /> <input type="button" value="json数组-->数组" onclick="f2()" /> </body> </html>
- Java转化为Json
- Java对象---->Json
- Java数组---->Json
- Java集合---->Json
package json; import java.util.ArrayList; import java.util.List; import org.junit.Test; import com.alibaba.fastjson.JSON; import entity.Employee; public class TestJson { //1.Java对象---->Json @Test public void test1(){ Employee employee = new Employee(1,"Hudie",7000.0,21); String jsonString = JSON.toJSONString(employee); System.out.println(jsonString); } //2.Java数组---->Json @Test public void test2(){ String[] a = new String[]{"a","b","c"}; String JsonString = JSON.toJSONString(a); System.out.println(JsonString); } //3.Java集合---->Json @Test public void test3(){ Employee employee1 = new Employee(1,"小a",3000.0,18); Employee employee2 = new Employee(2,"小b",4000.0,19); Employee employee3 = new Employee(3,"小c",5000.0,20); List<Employee> emps = new ArrayList<Employee>(); emps.add(employee1); emps.add(employee2); emps.add(employee3); String JsonString = JSON.toJSONString(emps); System.out.println(JsonString); } }
Employee雇员类:
package entity; /** * 雇员类 */ public class Employee { private Integer id; private String name; private Double salary; private Integer age; public Employee(Integer id, String name, Double salary, Integer age) { super(); this.id = id; this.name = name; this.salary = salary; this.age = age; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Double getSalary() { return salary; } public void setSalary(Double salary) { this.salary = salary; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } }
关于jQuery对Ajax的支持,datatype参数,服务器返回的数据类型如果是json会被转化为js:
regist_jquery.html:
<!DOCTYPE html> <html> <head> <title>regist_jquery.html</title> <meta charset="utf-8"/> <script src="js/jQuery-3.4.1.js"></script> <script type="text/javascript"> $(function(){ //用jQuery的方式发送Ajax请求 $("#bt1").click(function(){ //获取用户名和密码的值 var username = $("#username").val(); var password = $(":password").val(); $.ajax({ dataType:"Json", type:'post', url:"regist?username="+username+"&password="+password, async:true, success:function(data){ console.info(data); $("#sp").text(data); }, error:function(data){ alert("注册失败"); } }) }) }) </script> </head> <body> <form> 用户名: <input type="text" id="username" name="username" value="mary" /><span id="sp"></span><br /> 密码: <input type="password" name="password"><br /> 简介: <textarea rows="5" cols="22"></textarea><br /> <input type="button" id="bt1" value="get方式注册" /><br /> </form> </body> </html>
RegistServlet.java
package ajax; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.alibaba.fastjson.JSON; import entity.Employee; public class RegistServlet extends HttpServlet { @Override protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // request接收浏览器请求的对象 // response服务器端返回响应的对象 // 服务器端解决乱码 request.setCharacterEncoding("utf-8"); response.setContentType("text/html;charset=utf-8"); // 接收请求参数 String username = request.getParameter("username"); String password = request.getParameter("password"); // 获得响应流 PrintWriter out = response.getWriter(); // 做出响应 if (username.equals("gql")) { Employee employee = new Employee(1,"Hudie.",15000.0,19); Object Json = JSON.toJSON(employee); out.println(Json); } else { out.println("注册成功"); } out.close(); } }