2019-05-29
Ajax简介
Ajax(Asynchronous Javascript And XML)是一种全新的客户端与服务器之间的异步交互技术,整个交互过程无需重新加载整个客户端页面,可以实现页面的局部刷新。
XMLHttpRequest对象被称做Ajax引擎,该对象在JavaScript中创建并使用,它负责发送客户端对服务器端的请求;同时接收服务器端的响应信息,整个交互过程不必刷新当前页面
Ajax基本使用流程
创建Ajax对象
/*创建XMLHttpRequest对象, 各浏览器创建方式不统一*/
function createXMLHttpRequest() {
var xhr = null;
if (window.ActiveXObject) { //IE浏览器创建方式
xhr = new ActiveXObject("Microsoft.XMLHTTP");
} else if (window.XMLHttpRequest) { //非IE浏览器或IE7以上版本
xhr = new XMLHttpRequest();
}
if (!(xhr)) { //异常,创建对象失败
window.alert("创建XMLHttpRequest异常!");
}
return xhr;
}
创建Ajax请求
xhr.open(请求方式, 请求地址, true/false)
参数说明:
请求方式:get或post。get方式会使用缓存,post方式不使用缓存。
请求地址:目标服务器的URL。
注意:
可以将时间戳(如Math.random())追加到URL确保URL的唯一性,从而避免浏览器缓存结果。
布尔值:说明请求是否是异步模式。为true说明以异步模式发送请求,客户端不需等待服务器的响应;如果是同步方式(false),客户端要等到服务器返回消息后才能执行其它操作。默认为true。
监听服务器响应
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) { // 判断请求状态,4表示请求完成
if (xhr.status == 200) { // 响应成功返回200
//使用xhr对象的responseText属性读取服务器的响应信息(文本)
}
}
}
监听事件要在调用send方法发送请求之前设置。
readyState属性表示Ajax请求的当前状态。该属性在向服务器发送请求到接收服务器响应的期间会陆续发生状态变化,每当readyState属性值发生变化时都会触发readystatechange事件。
readyState属性值:
状态码 | 说明 |
---|---|
0 | 未初始化,XHR对象已经创建,但还没有调用open方法。 |
1 | 载入中,对象已经初始化,open方法已经调用,但尚未调用send方法发送请求,处于准备发送状态。 |
2 | 数据已加载,已经调用send方法把一个请求发送到服务器端,但还没有收到响应。 |
3 | 交互中,表示正在接收的状态,此时已经接收到HTTP响应头部信息,但消息体部分还没有完全接收结束。 |
4 | 完成,已加载完毕状态。此时响应已经被完全接收。连接已经关闭。 |
唯一可靠的readyState值是4。有些浏览器忽略1和2状态,有些浏览器在响应完成之前将触发多次3状态。
HTTP状态码
状态码 | 说 明 |
---|---|
200 | 服务器响应正常 |
400 | 无法找到请求的资源 |
403 | 没有访问权限 |
404 | 访问的资源不存在 |
500 | 服务器内部错误 |
就绪状态是4而且状态码是200,才可以处理服务器数据。因为即使服务器端错误,readyState属性的值仍然会设置为4,因此只检查readyState是不够的。
发送请求
//get方式
xhr.open("get","VerifyServlet?username="+username + "×=" + new Date().getTime(),true);
xhr.send();
//post方式
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
xhr.send("username="+username);
JSON应用
JSON是JavaScript原生对象,是无序的键/值对集合。对象以{}包围,键值之间用冒号分隔;键值对之间使用","分隔。
{key:value,key:value,key:value}
服务器端可以将响应信息以JSON格式的字符串返回到前端,JS可以使用以下方式将字符串解析为JSON对象进行读取:
//方式一:使用eval函数
eval("(" + 字符串 + ")")
//方式二:使用JSON对象
JSON.parse(字符串);//将字符串解析为JSON
JSON.stringify(JSON对象);//将JSON解析为字符串
//方式三:使用jQuery
$.parseJSON(字符串)
WebSocket
WebSocket是HTML5开始提供的一种基于TCP协议的浏览器与服务器间进行全双工通信的网络技术。依靠这种技术可以实现客户端和服务器端的长连接,双向实时通信,并允许服务器主动发送信息给客户端。
Tomcat从7.0.27开始支持 WebSocket。
- 客户端通过JavaScript向服务器端发起连接请求
- 服务器端接收请求,建立长连接
- 客户端与服务器端进行双向全双工通信
客户端示例:
window.onload=function(){
var websocket = null;
//判断当前浏览器是否支持WebSocket
if ('WebSocket' in window) {
websocket = new WebSocket("ws://localhost:8080/MyApp/websocket");//服务器连接点
}else {
alert('当前浏览器不支持websocket');
}
//连接发生错误的回调方法
websocket.onerror = function () {
console.log("WebSocket连接发生错误");
};
//连接成功建立的回调方法
websocket.onopen = function () {
websocket.send("向服务器发送消息");
console.log("WebSocket连接成功");
};
//接收到消息的回调方法
websocket.onmessage = function (event) {
console.log(event.data);//打印消息
};
//连接关闭的回调方法
websocket.onclose = function () {
console.log("WebSocket连接关闭");
};
//监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,
//防止连接还没断开就关闭窗口,server端会抛异常。
window.onbeforeunload = function () {
websocket.close();//关闭WebSocket连接
};
}
服务端示例:
import java.io.IOException;
import java.util.concurrent.CopyOnWriteArraySet;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
@ServerEndpoint("/websocket") //添加ServerEndpoint注解
public class WebSocketTest {
// concurrent包的线程安全Set,用来存放每个客户端对应的Session对象。
private static CopyOnWriteArraySet<Session> sessions = new CopyOnWriteArraySet<Session>();
/**
* 连接建立成功调用的方法
*
* @param session 与某个客户端的连接会话,需要通过它来给客户端发送数据
*/
@OnOpen
public void onOpen(Session session) {
sessions.add(session); // 加入set中
System.out.println("连接建立");
}
/**
* 连接关闭调用的方法
*/
@OnClose
public void onClose(Session session) {
sessions.remove(session); // 从set中删除
System.out.println("连接关闭");
}
/**
* 收到客户端消息后调用的方法
*
* @param message 客户端发送过来的消息
* @param session 可选的参数
*/
@OnMessage
public void onMessage(String message, Session session) {
System.out.println("来自客户端的消息:" + message);
}
/**
* 发生错误时调用
*
* @param session
* @param error
*/
@OnError
public void onError(Session session, Throwable error) {
System.out.println("发生错误");
error.printStackTrace();
}
/**
* 向客户端发送消息
*
* @param message
* @throws IOException
*/
public void sendMessage(String message) throws IOException {
// 群发消息
for (Session item : sessions) {
try {
item.getAsyncRemote().sendText(message);
} catch (Exception e) {
e.printStackTrace();
continue;
}
}
}
}
FormData对象
FormData是XMLHttpRequest Level2新增的一个对象,可以通过Ajax方式提交表单,并可以上传二进制文件。
通过FormData对象发送表单数据
var xhr = ...;
xhr.open(...);
var form = document.getElementById("form1");
var fd = new FormData(form);
xhr.send(fd);
-
Ajax请求类型应设置为post
-
表单元素要有明确的name属性
-
服务器端Servlet应符合Servlet3.0规范,使用注解方式进行配置。
@MultipartConfig @WebServlet("/LoginServlet")
通过FormData对象发送任意键值对
var fd = new FormData();
fd.append(键,值); //参数值将自动转化为字符串
xhr.send(fd);
通过FormData对象进行文件上传
使用方式与以上两者相同,只需要在表单中加入文件域即可,不必进行enctype="multipart/form-data"
编码
新版本的XMLHttpRequest对象传送数据时有一个progress事件,用来返回进度信息。它分成上传和下载两种情况。下载的progress事件属于XMLHttpRequest对象,上传的progress事件属于XMLHttpRequest.upload对象。
progress事件触发时会返回event对象,event.loaded属性表示已经传输的字节数;event.total表示需要传输的总字节数。
xhr.upload.onprogress = function(event){
var loaded = event.loaded;//已经传输的字节
var total = event.total;//需要传输的总字节
var per = Math.floor((loaded/total)*100);
progress1.value = per;
}
可给文件域增加multiple="multiple"属性实现多文件上传,需要在js中添加处理代码给每个文件添加不同的文件名。
//多文件上传------------------------------------
var fd = new FormData();
var arr = document.getElementById("photo").files;
for (var i = 0; i < arr.length; i++) {
fd.append("photo" + i, arr[i]);
}
xhr.send(fd);
网友评论