# ajex相關知識與使用
###### tags: `Java Web-vue`
### 同步請求vs異步請求
#### 同步請求(Synchronous request):
客戶端 (client) 對伺服器端 (server) 送出 request ,並且在收到伺服器端的 response 之後才會繼續下一步的動作,等待的期間無法處理其他事情。這個作法並不理想,因為通常伺服器端的運算速度比本地電腦慢上好幾倍。

#### 異步請求(Asynchronous request):
客戶端 (client) 對伺服器端 (server) 送出 request 之後,不需要等待結果,仍可以持續處理其他事情,甚至繼續送出其他 request。Responese 傳回之後,就被融合進當下頁面或應用中。

#### 兩者運行差異

### 示範
#### 驗證此用戶名是否被重複使用
1.利用onblur,在鼠標焦點移開時,執行ckUname()方法
```htmlembedded=
<input id="unameTxt" type="text" placeholder="请输入用户名" name="uname" value="hello2022" onblur="ckUname(this.value)"/>
```
2.打造ckUname()方法
```json=
//如果想要发送异步请求,我们需要一个关键的对象 XMLHttpRequest
var xmlHttpRequest ;
function createXMLHttpRequest(){
//針對不同瀏覽器,創建對象的方式也不同
if(window.XMLHttpRequest){
//符合DOM2标准的浏览器 ,xmlHttpRequest的创建方式
xmlHttpRequest = new XMLHttpRequest() ;
}else if(window.ActiveXObject){//IE浏览器
try{
xmlHttpRequest = new ActiveXObject("Microsoft.XMLHTTP");
}catch (e) {
xmlHttpRequest = new ActiveXObject("Msxml2.XMLHTTP")
}
}
}
function ckUname(uname){
createXMLHttpRequest();
var url = "user.do?operate=ckUname&uname="+uname ;
xmlHttpRequest.open("GET",url,true);
//设置回调函数
xmlHttpRequest.onreadystatechange = ckUnameCB ;
//发送请求
xmlHttpRequest.send();
}
function ckUnameCB(){
if(xmlHttpRequest.readyState==4 && xmlHttpRequest.status==200){
//xmlHttpRequest.responseText 表示 服务器端响应给我的文本内容
//alert(xmlHttpRequest.responseText);
var responseText = xmlHttpRequest.responseText ;
// {'uname':'1'}
//alert(responseText);
if(responseText=="{'uname':'1'}"){
alert("用户名已经被注册!");
}else{
alert("用户名可以注册!");
}
}
}
```
3.控制器寫方法
```java=
public String ckUname(String uname){
User user = userService.getUser(uname);
if(user!=null){
//用户名已经被占用,不可以注册
//傳給客戶端的字符串
return "json:{'uname':'1'}";
//return "ajax:1";
}else{
//用户名可以注册
return "json:{'uname':'0'}";
//return "ajax:0";
}
}
```
4.在DispatcherServlet的視圖處理中,追加"json:"的判斷
```java=
//3.视图处理
String methodReturnStr = (String)returnObj ;
if(methodReturnStr.startsWith("redirect:")){ //比如: redirect:fruit.do
String redirectStr = methodReturnStr.substring("redirect:".length());
response.sendRedirect(redirectStr);
}else if(methodReturnStr.startsWith("json:")){
//截斷前面的json:
String jsonStr = methodReturnStr.substring("json:".length());
PrintWriter out = response.getWriter();
//發出後面的數字(0、1)
out.print(jsonStr);
out.flush();
}else{
super.processTemplate(methodReturnStr,request,response); // 比如: "edit"
}
}
}
/*
}else{
throw new RuntimeException("operate值非法!");
}
*/
} catch (Exception e) {
e.printStackTrace();
throw new DispatcherServletException("DispatcherServlet出错了...");
}
}
```
## 原生的Ajax(了解)
### 第一步: 客户端发送异步请求;并绑定对结果处理的回调函数
1) <input type="text" name="uname" onblur="ckUname()"/>
2) 定义ckUname方法:
- 创建XMLHttpRequest对象
- XMLHttpRequest对象操作步骤:
- open(url,"GET",true)
- onreadyStateChange 设置回调
- send() 发送请求
- 在回调函数中需要判断XMLHttpRequest对象的状态:
readyState(0-4) , status(200)
### 第二步:服务器端做校验,然后将校验结果响应给客户端
****************
## Ajax : 异步的JavaScript and XML
#### 目的: 用来发送异步的请求,然后当服务器给我响应的时候再进行回调操作
#### 好处: 提高用户体验;局部刷新:降低服务器负担、减轻浏览器压力、减轻网络带宽压力
#### 开发步骤:
1) 创建XMLHttpRequest
2) 调用open进行设置:"GET" , URL , true
3) 绑定状态改变时执行的回调函数 - onreadystatechange
4) 发送请求 - send()
5) 编写回调函数,在回调函数中,我们只对XMLHttpRequest的readystate为4的时候感兴趣
我们只对XMLHttpRequest的status为200的时候感兴趣
0: (Uninitialized) the send( ) method has not yet been invoked.
1: (Loading) the send( ) method has been invoked, request in progress.
2: (Loaded) the send( ) method has completed, entire response received.
3: (Interactive) the response is being parsed.
4: (Completed) the response has been parsed, is ready for harvesting.
0 - (未初始化)还没有调用send()方法
1 - (载入)已调用send()方法,正在发送请求
2 - (载入完成)send()方法执行完成,已经接收到全部响应内容
3 - (交互)正在解析响应内容
4 - (完成)响应内容解析完成,可以在客户端调用了