AJAX教程
1、AJAX
1.1 全局刷新和局部刷新
1.1.1 全局刷新
1.1.2 局部刷新
1.1.2.1 异步请求对象
1.1.2.2 什么是Ajax
1.1.2.3 XMLHttpRequest 对象
1.2 AJAX运行原理及实现
;
// Ajax对象要向哪发送请求,以什么方式发送请求
xhr.open('get','http://localhost:3000/responseData');
// 发送请求
xhr.send();
// 获取服务器端响应到客户端的数据
xhr.onload = function() {
// console.log(xhr.responseText);
var responseText = JSON.parse(xhr.responseText); // 将JSON字符串转换为JSON对象
console.log(responseText)
var str = '<h2>' + responseText.name + '</h2>'
document.body.innerHTML = str;
};
</script>
1.2.6 请求的参数传递
1.2.6.1 请求报文
1.2.6.2 GET请求方式
<body>
<p>
<input type="text" id="username" >
</p>
<p>
<input type="text" id="age" >
</p>
<p>
<input type="button" value="提交" id="btn">
</p>
<script>
// 获取按钮元素
var btn = document.getElementById('btn');
// 获取姓名文本框
var username = document.getElementById('username');
// 获取年龄文本框
var age = document.getElementById('age');
btn.onclick = function() {
// 创建Ajax对象
var xhr = new XMLHttpRequest();
// 获取用户在文本框中输入的值
var nameValue = username.value;
var ageValue = age.value;
// ajax中的参数需要自己拼接,传统方法不需要拼接参数 然后传递给服务器端
var params = 'username='+ nameValue +'&age='+ ageValue;
// 配置ajax对象 把拼接好的参数传给初始化异步请求对象
xhr.open('get','http://localhost:3000/get?' + params);
// 发送请求
xhr.send();
// 获取服务端响应的数据
xhr.onload = function() {
console.log(xhr.responseText);
};
}
</script>
</body>
1.2.6.3 POST请求方式
<body>
<p>
<input type="text" id="username" >
</p>
<p>
<input type="text" id="age" >
</p>
<p>
<input type="button" value="提交" id="btn">
</p>
<script>
// 获取按钮元素
var btn = document.getElementById('btn');
// 获取姓名文本框
var username = document.getElementById('username');
// 获取年龄文本框
var age = document.getElementById('age');
btn.onclick = function() {
// 创建Ajax对象
var xhr = new XMLHttpRequest();
// 获取用户在文本框中输入的值
var nameValue = username.value;
var ageValue = age.value;
// ajax中的参数需要自己拼接,传统方法不需要拼接参数 然后传递给服务器端
var params = 'username='+ nameValue +'&age='+ ageValue;
// 配置ajax对象
xhr.open('post','http://localhost:3000/post');
// 设置请求参数格式的类型 (post请求必须要设置)
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
// 发送请求 把拼接好的参数传给异步对象发送请求
xhr.send(params);
// 获取服务端响应的数据
xhr.onload = function() {
console.log(xhr.responseText);
};
}
</script>
</body>
1.2.7 请求参数的格式
1.2.8 JSON
1.2.8.1 JSON格式特征
- JSON 的语法规则
+ JOSN 的 6 种数据类型
<script>
// 创建ajax对象
var xhr = new XMLHttpRequest();
// 告诉Ajax对象要向哪发送请求,以什么方式发送请求
// 1) 请求方式 2)请求地址
xhr.open('post', 'http://localhost:3000/json');
// 通过请求头告诉服务器端,客户端向服务端传递的请求参数的格式是什么
xhr.setRequestHeader('Content-Type', 'application/json');
// 发送请求 请求参数必须是字符串
// JSON对象数据转换成JSON字符串
xhr.send(JSON.stringify({name: 'lisi', age: 50}));
// 获取服务器端响应到客户端的数据
xhr.onload = function() {
console.log(xhr.responseText);
};
</script>
1.2.8.2 Jackson的使用
- 在响应中通过 JSON 格式传递数据
-
- 通过 JSON 格式在响应中传递单个对象
- 通过 JSON 格式在响应中传递单个对象
package com.test.pojo;
public class Users {
private int userid;
private String username;
public int getUserid() {
return userid;
}
public void setUserid(int userid) {
this.userid = userid;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}
package com.test.servlet;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.test.pojo.Users;
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;
/**
* 通过JSON格式响应单个对象
*/
@WebServlet("/single.do")
public class SingleObjectServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 创建Users对象
Users users = new Users();
users.setUserid(1);
users.setUsername("AAA1");
// 使用jackson的API将Users对象转换为JSON格式的对象
ObjectMapper objectMapper = new ObjectMapper();
// 将Users对象转换为JSON格式的字符串对象
String string = objectMapper.writeValueAsString(users);
System.out.println(string);
// 设置响应类型为application/json
resp.setContentType("application/json");
PrintWriter pw = resp.getWriter();
pw.print(string);
pw.flush();
pw.close();
}
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<script>
function but() {
var xhr = new XMLHttpRequest();
xhr.open("get","single.do");
xhr.send();
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
alert(xhr.responseText);
// 通过javaScript的内置对象JSON中的parse函数将JSON格式的字符串对象转化为JS对象
var obj = JSON.parse(xhr.responseText);
alert(obj.userid + " " + obj.username);
document.getElementById("span").innerHTML = obj.userid + "<br>" + obj.username;
}
}
}
</script>
</head>
<body>
<h3>JSON格式的单个对象响应</h3>
<hr>
<span id="span"></span>
<input type="button" value="ok" onclick="but()">
</body>
</html>
-
- 通过 JSON 格式在响应中传递多个对象
- 通过 JSON 格式在响应中传递多个对象
package com.test.pojo;
public class Users {
private int userid;
private String username;
public int getUserid() {
return userid;
}
public void setUserid(int userid) {
this.userid = userid;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}
package com.test.servlet;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.test.pojo.Users;
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;
import java.util.ArrayList;
import java.util.List;
/**
* 通过JSON格式响应对个对象
*/
@WebServlet("/multiple.do")
public class MultipleObjectServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Users users1 = new Users();
users1.setUserid(1);
users1.setUsername("AAA1");
Users users2 = new Users();
users2.setUserid(2);
users2.setUsername("BBB1");
// 需要将多个对象放入到集合中
List<Users> list = new ArrayList<>();
list.add(users1);
list.add(users2);
// 通过jackson将List转换为JSON格式的字符串对象
ObjectMapper objectMapper = new ObjectMapper();
String str = objectMapper.writeValueAsString(list);
System.out.println(str);
resp.setContentType("application/json");
PrintWriter pw = resp.getWriter();
pw.print(str);
pw.flush();
pw.close();
}
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<script>
function but() {
var xhr = new XMLHttpRequest();
xhr.open("get","multiple.do");
xhr.send();
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
alert(xhr.responseText);
// 通过javaScript的内置对象JSON中的parse函数将JSON格式的字符串对象转化为JS对象
var obj = JSON.parse(xhr.responseText);
var temp = "";
for (i = 0; i < obj.length; i++) {
alert(obj[i].userid + " " + obj[i].username);
temp += obj[i].userid + " " + obj[i].username + "<br>";
}
document.getElementById("span").innerHTML = temp;
}
}
}
</script>
</head>
<body>
<h3>JSON格式的多个对象响应</h3>
<hr>
<span id="span"></span>
<input type="button" value="ok" onclick="but()">
</body>
</html>
-
- 在 JSON 中通过 Map 传递数据
- 在 JSON 中通过 Map 传递数据
package com.test.pojo;
public class Users {
private int userid;
private String username;
public int getUserid() {
return userid;
}
public void setUserid(int userid) {
this.userid = userid;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}
package com.test.servlet;
import com.fasterxml.jackson.databind.ObjectMapper;
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;
import java.util.HashMap;
import java.util.Map;
@WebServlet("/map.do")
public class MapModelServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Map<String, Object> map = new HashMap<>();
map.put("userid", 1);
map.put("url","map.do");
ObjectMapper objectMapper = new ObjectMapper();
String str = objectMapper.writeValueAsString(map);
System.out.println(str);
resp.setContentType("application/json");
PrintWriter pw = resp.getWriter();
pw.print(str);
pw.flush();
pw.close();
}
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<script>
function but() {
var xhr = new XMLHttpRequest();
xhr.open("get","map.do");
xhr.send();
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
alert(xhr.responseText);
// 通过javaScript的内置对象JSON中的parse函数将JSON格式的字符串对象转化为JS对象
var obj = JSON.parse(xhr.responseText);
alert(obj.userid + " " + obj.url)
document.getElementById("span").innerHTML = obj.userid + "<br>" + obj.url;
}
}
}
</script>
</head>
<body>
<h3>Map模型的使用</h3>
<hr>
<span id="span"></span>
<input type="button" value="ok" onclick="but()">
</body>
</html>
- 在请求中通过 JSON 格式传递数据
package com.test.servlet;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.test.pojo.Users;
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;
/**
* 在请求中通过JSON格式传递数据
*/
@WebServlet("/json.do")
public class RequestJSONServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 从请求体中获取提交的JSON格式的数据
req.setCharacterEncoding("utf-8");
String s = req.getReader().readLine();
//使用Jackson将JSON格式的字符串对象转换成java对象
ObjectMapper objectMapper = new ObjectMapper();
Users users = objectMapper.readValue(s, Users.class);
System.out.println(users.getUserid() + " " + users.getUsername());
resp.setContentType("application/json");
PrintWriter pw = resp.getWriter();
pw.print("ok");
pw.flush();
pw.close();
}
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<script>
function but() {
var id = document.getElementById("userid").value;
var name = document.getElementById("username").value;
var obj = {userid: id, username: name};
var content = JSON.stringify(obj);
var xhr = new XMLHttpRequest();
xhr.open("post","json.do");
xhr.send(content);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
alert(xhr.responseText);
document.getElementById("span").innerHTML = xhr.responseText;
}
}
}
</script>
</head>
<body>
<h3>在请求中通过JSON格式传递数据</h3>
用户ID:<input type="text" name="userid" id="userid"> <br>
用户姓名:<input type="text" name="username" id="username"> <br>
<hr>
<span id="span"></span>
<input type="button" value="ok" onclick="but()">
</body>
</html>
- Jackson 的常用注解
-
- @JsonProperty
此注解用于属性上,作用是把该属性的名称序列化为另外一个名称,如把 username 属
性序列化为 name,@JsonProperty(“name”)。
- @JsonProperty
-
- @JsonIgnore
此注解用于属性或者方法上(一般都是定义在属性上),用来完全忽略被注解的字段和
方法对应的属性,返回的 json 数据即不包含该属性。
- @JsonIgnore
-
- @JsonFormat
此注解用于属性或者方法上(一般都是定义在属性上),可以方便的把 Date 类型属性
的值直接转化为我们想要的样式。如:@JsonFormat(pattern=“yyyy-MM-dd hh:mm:ss”)
- @JsonFormat
package com.test.pojo;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.Date;
public class Users {
@JsonIgnore // 忽略了userid,如果在注解的上面,就忽略注解
private int userid;
@JsonProperty("name") // 把username的属性改成name的注解
private String username;
@JsonFormat(pattern = "yyyy-MM-dd")
private Date userbirth;
public Date getUserbirth() {
return userbirth;
}
public void setUserbirth(Date userbirth) {
this.userbirth = userbirth;
}
public int getUserid() {
return userid;
}
public void setUserid(int userid) {
this.userid = userid;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}
package com.test.servlet;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.test.pojo.Users;
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;
import java.util.Date;
/**
* Jackson常用注解的使用
*/
@WebServlet("/ann.do")
public class AnnotationServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Users users = new Users();
users.setUserid(1);
users.setUsername("AAAA1");
users.setUserbirth(new Date());
ObjectMapper objectMapper = new ObjectMapper();
String str = objectMapper.writeValueAsString(users);
System.out.println(str);
resp.setContentType("application/json");
PrintWriter pw = resp.getWriter();
pw.print("hello");
pw.flush();
pw.close();
}
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<script>
function but() {
var xhr = new XMLHttpRequest();
xhr.open("get","ann.do");
xhr.send();
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
alert(xhr.responseText);
document.getElementById("span").innerHTML = xhr.responseText;
}
}
}
</script>
</head>
<body>
<h3>JSON常用注解</h3>
<hr>
<span id="span"></span>
<input type="button" value="ok" onclick="but()">
</body>
</html>
- Jackson 工具类的使用
package com.test.servlet;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.List;
/**
* JSON 转换工具类
*/
public class JsonUtils {
// 定义 jackson 对象
private static final ObjectMapper MAPPER = new ObjectMapper();
/**
* 将对象转换成 json 字符串。
* <p>Title: pojoToJson</p>
* <p>Description: </p>
* @param data
* @return
*/
public static String objectToJson(Object data) {
try {
String string = MAPPER.writeValueAsString(data);
return string;
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return null;
}
/**
* 将 json 结果集转化为对象
* @param jsonData json 数据
* @param beanType 对象中的 object 类型
* @return
*/
public static <T> T jsonToPojo(String jsonData, Class<T> beanType) {
try {
T t = MAPPER.readValue(jsonData, beanType);
return t;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 将 json 数据转换成 pojo 对象 list
* <p>Title: jsonToList</p>
* <p>Description: </p>
* @param jsonData
* @param beanType
* @return
*/
public static <T> List<T> jsonToList(String jsonData, Class<T> beanType) {
JavaType javaType = MAPPER.getTypeFactory().constructParametricType(List.class, beanType);
try {
List<T> list = MAPPER.readValue(jsonData, javaType);
return list;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
package com.test.servlet;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.test.pojo.Users;
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;
import java.util.Date;
/**
* Jackson常用注解的使用
*/
@WebServlet("/ann.do")
public class AnnotationServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Users users = new Users();
users.setUserid(1);
users.setUsername("AAAA1");
users.setUserbirth(new Date());
// ObjectMapper objectMapper = new ObjectMapper();
// String str = objectMapper.writeValueAsString(users);
// 使用JackSon工具包
String str = JsonUtils.objectToJson(users);
System.out.println(str);
resp.setContentType("application/json");
PrintWriter pw = resp.getWriter();
pw.print("hello");
pw.flush();
pw.close();
}
}
1.2.9 获取服务器端的响应
1.2.9.1 Ajax 状态码
1.2.9.2 onreadystatechange 事件
1.2.9.3 两种获取服务端响应方式的区别
<script>
// 创建Ajax对象
var xhr = new XMLHttpRequest();
console.log(xhr.readyState); // 0 表示已经创建了ajax对象,但还没有对ajax对象进行配置
// 对ajax进行配置
xhr.open('get', 'http://localhost:3000/readystate');
console.log(xhr.readyState); // 1 已经对ajax进行配置,但是还没有发送请求
// 发送请求 此时的ajax的状态码处于变化的状态
// 所以需要onreadystatechange事件来监听ajax的状态码值;如果ajax的状态码发生变化,才触发onreadystatechange事件
// 只要ajax的状态码发生了变化,就调用onreadystatechange事件
xhr.onreadystatechange = function() {
// 2 3 4 都是在onreadystatechange事件中触发的
// 2 代表请求已经发送了
// 3 已经接收到服务器端的部分数据了
// 4 服务器端的响应数据已经接收完成
console.log(xhr.readyState);
// 对ajax状态码进行判断 如果状态码的值为4就代表数据已经接受完成了
if (xhr.readyState == 4 && xhr.status == 200) {
// ajax状态码为4 表示数据接收已经完成,所以就可以获取和使用数据了
console.log(xhr.responseText);
}
};
xhr.send()
// console.log(xhr.readyState); // 此时ajax的状态码是变化的,因此打印的结果是看不到效果的
</script>
1.2.10 Ajax错误处理
<body>
<button id="btn">发送Ajax请求</button>
<script>
var btn = document.getElementById('btn');
btn.onclick = function() {
var xhr = new XMLHttpRequest();
xhr.open('get', 'http://localhost:3000/error');
xhr.send();
xhr.onload = function() {
console.log(xhr.responseText);
// xhr.status 获取http状态码
if (xhr.status == 400) {
alert('请求出错');
}
};
// 当网络中断时触发onerror事件
xhr.onerror = function() {
alert('网络中断,无法发送Ajax请求');
};
};
// Ajax状态码:表示Ajax请求的过程状态 ajax对象返回的
// Http状态码:表示请求的处理结果 是服务器返回的
</script>
</body>
1.2.11 低版本IE浏览器的缓存问题
<body>
<button id="btn">发送Ajax请求</button>
<script>
var btn = document.getElementById('btn');
btn.onclick = function() {
var xhr = new XMLHttpRequest();
// 低版本IE浏览器会出现缓存问题
// xhr.open('get', 'http://localhost:3000/cache');
// 在请求地址的后面加上随机参数,就能解决低版本IE浏览器的缓存问题
xhr.open('get', 'http://localhost:3000/cache?t=' + Math.random());
xhr.send();
// 低版本IE浏览器不支持onload
xhr.onreadystatechange = function() {
// 请求发送成功
if (xhr.readyState == 4 && xhr.status == 200) {
alert(xhr.responseText);
}
};
};
</script>
</body>
2、AJAX 异步编程
2.1 同步异步概述
2.1.1 同步
2.1.2 异步
2.2 Ajax封装
- ajax.js
// Ajax封装
<script>
function ajax(defaults) {
// 存储默认值,用户没有传值,就用默认值
var defaults = {
type: 'get',
url: '',
data: {},
header: {
'Content-Type': 'application/x-www-form-urlencoded'
},
success: function() {},
error: function() {}
};
// 用户有传值,需覆盖默认值
Object.assign(defaults,options);
// 创建Ajax对象
var xhr = new XMLHttpRequest();
// 拼接请求参数的变量
var params = '';
// 循环遍历
for (var attr in defaults.data) {
// 参数拼接
params += attr + '=' + defaults.data[attr] + '&';
}
// 对最后一个&,要截取掉
params = params.substr(0,params.length - 1); // 字符串的截取
// console.log(params); // 测试参数的拼接的结果
// 判断请求方式
if (defaults.type == 'get') {
defaults.url += '?' + params;
}
// 配置Ajax对象
// 1) 请求方式 2)请求地址
xhr.open(defaults.type, defaults.url);
// 如果请求方式为post
if (defaults.type == 'post') {
// 用户向服务器传递的请求参数的类型
var contentType = defaults.header['Content-Type'];
// 设置请求参数格式的类型
xhr.setRequestHeader('Content-Type', contentType);
// 对参数类型判断
if (contentType == 'application/json') {
// JSON对象数据转换成JSON字符串
xhr.send(JSON.stringify(defaults.data));
} else {
// 发送拼接的字符串
xhr.send(params);
}
} else {
// 发送请求
xhr.send();
}
// 监听xhr对象下面的onload事件
// 当xhr对象接收完响应数据后触发
xhr.onload = function () {
// 获取响应头中的数据
var contentType = xhr.getResponseHeader('Content-Type');
// 服务器端返回的数据
var responseText = xhr.responseText;
// 响应类型的判断
if (contentType.includes('application/json')) {
// JSON字符串转换成JSON对象
responseText = JSON.parse(responseText);
}
// Http的状态码判断
// 调用success、error 把xhr对象也一并返回,这样就能得到xhr对象里更多信息,为后续判断做铺垫
if (xhr.status == 200) {
// 请求成功,调用处理成功情况的函数
defaults.success(responseText, xhr);
} else {
// 请求失败,调用处理失败情况的函数
defaults.error(responseText, xhr);
}
};
}
// 如果用户有传值,就使用用户传入的数据
ajax({
// 请求方式
type: 'post',
url: 'http://localhost:3000/first',
// 传递对象类型对于函数的调用者更加友好
// 在函数内部对象数据类型转换为字符串数据类型更加方便
// url中的参数定义为对象数据类型
data: {
name: 'zhangsan',
age: 20
},
// 请求参数格式类型数据定义为对象数据类型
header: {
// 参数数据格式类型为JSON
'Content-Type': 'application/json'
},
// 请求成功函数
success: function(data,xhr) {
console.log('这是请求成功函数:' + data);
console.log(xhr)
},
// 请求失败函数
error: function(data,xhr) {
console.log('这是请求失败函数:' + data);
console.log(xhr)
}
});
// 如果没有传值,则ajax()参数就使用默认值 defaults
// ajax({
// url: 'http://localhost:3000/first',
// // 传递对象类型对于函数的调用者更加友好
// // 在函数内部对象数据类型转换为字符串数据类型更加方便
// // url中的参数定义为对象数据类型
// data: {
// name: 'zhangsan',
// age: 20
// },
// // 请求成功函数
// success: function(data,xhr) {
// console.log('这是请求成功函数:' + data);
// console.log(xhr)
// },
// // 请求失败函数
// error: function(data,xhr) {
// console.log('这是请求失败函数:' + data);
// console.log(xhr)
// }
// });
</script>
2.3 模板引擎
2.3.1 模板引擎概述
2.3.2 模板引擎使用步骤
- template-web.js
/*! art-template@4.13.2 for browser | https://github.com/aui/art-template */
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.template=t():e.template=t()}("undefined"!=typeof self?self:this,function(){return function(e){function t(r){if(n[r])return n[r].exports;var i=n[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,t),i.l=!0,i.exports}var n={};return t.m=e,t.c=n,t.d=function(e,n,r){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:r})},t.n=function(e){var n=e&&e.__esModule?function(){return e["default"]}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=4)}([function(e,t,n){"use strict";var r=n(6),i=n(2),o=n(22),s=function(e,t){t.onerror(e,t);var n=function(){return"{Template Error}"};return n.mappings=[],n.sourcesContent=[],n},a=function u(e){var t=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};"string"!=typeof e?t=e:t.source=e,t=i.$extend(t),e=t.source,!0===t.debug&&(t.cache=!1,t.minimize=!1,t.compileDebug=!0),t.compileDebug&&(t.minimize=!1),t.filename&&(t.filename=t.resolveFilename(t.filename,t));var n=t.filename,a=t.cache,c=t.caches;if(a&&n){var l=c.get(n);if(l)return l}if(!e)try{e=t.loader(n,t),t.source=e}catch(m){var f=new o({name:"CompileError",path:n,message:"template not found: "+m.message,stack:m.stack});if(t.bail)throw f;return s(f,t)}var p=void 0,h=new r(t);try{p=h.build()}catch(f){if(f=new o(f),t.bail)throw f;return s(f,t)}var d=function(e,n){try{return p(e,n)}catch(f){if(!t.compileDebug)return t.cache=!1,t.compileDebug=!0,u(t)(e,n);if(f=new o(f),t.bail)throw f;return s(f,t)()}};return d.mappings=p.mappings,d.sourcesContent=p.sourcesContent,d.toString=function(){return p.toString()},a&&n&&c.set(n,d),d};a.Compiler=r,e.exports=a},function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t["default"]=/((['"])(?:(?!\2|\\).|\\(?:\r\n|[\s\S]))*(\2)?|`(?:[^`\\$]|\\[\s\S]|\$(?!\{)|\$\{(?:[^{}]|\{[^}]*\}?)*\}?)*(`)?)|(\/\/.*)|(\/\*(?:[^*]|\*(?!\/))*(\*\/)?)|(\/(?!\*)(?:\[(?:(?![\]\\]).|\\.)*\]|(?![\/\]\\]).|\\.)+\/(?:(?!\s*(?:\b|[\u0080-\uFFFF$\\'"~({]|[+\-!](?!=)|\.?\d))|[gmiyu]{1,5}\b(?![\u0080-\uFFFF$\\]|\s*(?:[+\-*%&|^<>!=?({]|\/(?![\/*])))))|(0[xX][\da-fA-F]+|0[oO][0-7]+|0[bB][01]+|(?:\d*\.\d+|\d+\.?)(?:[eE][+-]?\d+)?)|((?!\d)(?:(?!\s)[$\w\u0080-\uFFFF]|\\u[\da-fA-F]{4}|\\u\{[\da-fA-F]+\})+)|(--|\+\+|&&|\|\||=>|\.{3}|(?:[+\-\/%&|^]|\*{1,2}|<{1,2}|>{1,3}|!=?|={1,2})=?|[?~.,:;[\](){}])|(\s+)|(^$|[\s\S])/g,t.matchToToken=function(e){var t={type:"invalid",value:e[0]};return e[1]?(t.type="string",t.closed=!(!e[3]&&!e[4])):e[5]?t.type="comment":e[6]?(t.type="comment",t.closed=!!e[7]):e[8]?t.type="regex":e[9]?t.type="number":e[10]?t.type="name":e[11]?t.type="punctuator":e[12]&&(t.type="whitespace"),t}},function(e,t,n){"use strict";function r(){this.$extend=function(e){return e=e||{},o(e,e instanceof r?e:this)}}var i=n(10),o=n(12),s=n(13),a=n(14),u=n(15),c=n(16),l=n(17),f=n(18),p=n(19),h=n(21),d="undefined"==typeof window,m={source:null,filename:null,rules:[f,l],escape:!0,debug:!!d&&"production"!==process.env.NODE_ENV,bail:!0,cache:!0,minimize:!0,compileDebug:!1,resolveFilename:h,include:s,htmlMinifier:p,htmlMinifierOptions:{collapseWhitespace:!0,minifyCSS:!0,minifyJS:!0,ignoreCustomFragments:[]},onerror:a,loader:c,caches:u,root:"/",extname:".art",ignore:[],imports:i};r.prototype=m,e.exports=new r},function(e,t){},function(e,t,n){"use strict";var r=n(5),i=n(0),o=n(23),s=function(e,t){return t instanceof Object?r({filename:e},t):i({filename:e,source:t})};s.render=r,s.compile=i,s.defaults=o,e.exports=s},function(e,t,n){"use strict";var r=n(0),i=function(e,t,n){return r(e,n)(t)};e.exports=i},function(e,t,n){"use strict";function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e){if(Array.isArray(e)){for(var t=0,n=Array(e.length);t<e.length;t++)n[t]=e[t];return n}return Array.from(e)}function o(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var s=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),a=n(7),u=n(9),c="$data",l="$imports",f="print",p="include",h="extend",d="block",m="$$out",v="$$line",g="$$blocks",y="$$slice",b="$$from",w="$$options",x=function(e,t){return Object.hasOwnProperty.call(e,t)},k=JSON.stringify,E=function(){function e(t){var n,s,a=this;o(this,e);var x=t.source,k=t.minimize,E=t.htmlMinifier;if(this.options=t,this.stacks=[],this.context=[],this.scripts=[],this.CONTEXT_MAP={},this.ignore=[c,l,w].concat(i(t.ignore)),this.internal=(n={},r(n,m,"''"),r(n,v,"[0,0]"),r(n,g,"arguments[1]||{}"),r(n,b,"null"),r(n,f,"function(){var s=''.concat.apply('',arguments);"+m+"+=s;return s}"),r(n,p,"function(src,data){var s="+w+".include(src,data||"+c+",arguments[2]||"+g+","+w+");"+m+"+=s;return s}"),r(n,h,"function(from){"+b+"=from}"),r(n,y,"function(c,p,s){p="+m+";"+m+"='';c();s="+m+";"+m+"=p+s;return s}"),r(n,d,"function(){var a=arguments,s;if(typeof a[0]==='function'){return "+y+"(a[0])}else if("+b+"){if(!"+g+"[a[0]]){"+g+"[a[0]]="+y+"(a[1])}else{"+m+"+="+g+"[a[0]]}}else{s="+g+"[a[0]];if(typeof s==='string'){"+m+"+=s}else{s="+y+"(a[1])}return s}}"),n),this.dependencies=(s={},r(s,f,[m]),r(s,p,[m,w,c,g]),r(s,h,[b,p]),r(s,d,[y,b,m,g]),s),this.importContext(m),t.compileDebug&&this.importContext(v),k)try{x=E(x,t)}catch(T){}this.source=x,this.getTplTokens(x,t.rules,this).forEach(function(e){e.type===u.TYPE_STRING?a.parseString(e):a.parseExpression(e)})}return s(e,[{key:"getTplTokens",value:function(){return u.apply(undefined,arguments)}},{key:"getEsTokens",value:function(e){return a(e)}},{key:"getVariables",value:function(e){var t=!1;return e.filter(function(e){return"whitespace"!==e.type&&"comment"!==e.type}).filter(function(e){return"name"===e.type&&!t||(t="punctuator"===e.type&&"."===e.value,!1)}).map(function(e){return e.value})}},{key:"importContext",value:function(e){var t=this,n="",r=this.internal,i=this.dependencies,o=this.ignore,s=this.context,a=this.options,u=a.imports,f=this.CONTEXT_MAP;x(f,e)||-1!==o.indexOf(e)||(x(r,e)?(n=r[e],x(i,e)&&i[e].forEach(function(e){return t.importContext(e)})):n="$escape"===e||"$each"===e||x(u,e)?l+"."+e:c+"."+e,f[e]=n,s.push({name:e,value:n}))}},{key:"parseString",value:function(e){var t=e.value;if(t){var n=m+"+="+k(t);this.scripts.push({source:t,tplToken:e,code:n})}}},{key:"parseExpression",value:function(e){var t=this,n=e.value,r=e.script,i=r.output,o=this.options.escape,s=r.code;i&&(s=!1===o||i===u.TYPE_RAW?m+"+="+r.code:m+"+=$escape("+r.code+")");var a=this.getEsTokens(s);this.getVariables(a).forEach(function(e){return t.importContext(e)}),this.scripts.push({source:n,tplToken:e,code:s})}},{key:"checkExpression",value:function(e){for(var t=[[/^\s*}[\w\W]*?{?[\s;]*$/,""],[/(^[\w\W]*?\([\w\W]*?(?:=>|\([\w\W]*?\))\s*{[\s;]*$)/,"$1})"],[/(^[\w\W]*?\([\w\W]*?\)\s*{[\s;]*$)/,"$1}"]],n=0;n<t.length;){if(t[n][0].test(e)){var r;e=(r=e).replace.apply(r,i(t[n]));break}n++}try{return new Function(e),!0}catch(o){return!1}}},{key:"build",value:function(){var e=this.options,t=this.context,n=this.scripts,r=this.stacks,i=this.source,o=e.filename,s=e.imports,a=[],f=x(this.CONTEXT_MAP,h),d=0,y=function(e,t){var n=t.line,i=t.start,o={generated:{line:r.length+d+1,column:1},original:{line:n+1,column:i+1}};return d+=e.split(/\n/).length-1,o},E=function(e){return e.replace(/^[\t ]+|[\t ]$/g,"")};r.push("function("+c+"){"),r.push("'use strict'"),r.push(c+"="+c+"||{}"),r.push("var "+t.map(function(e){return e.name+"="+e.value}).join(",")),e.compileDebug?(r.push("try{"),n.forEach(function(e){e.tplToken.type===u.TYPE_EXPRESSION&&r.push(v+"=["+[e.tplToken.line,e.tplToken.start].join(",")+"]"),a.push(y(e.code,e.tplToken)),r.push(E(e.code))}),r.push("}catch(error){"),r.push("throw {"+["name:'RuntimeError'","path:"+k(o),"message:error.message","line:"+v+"[0]+1","column:"+v+"[1]+1","source:"+k(i),"stack:error.stack"].join(",")+"}"),r.push("}")):n.forEach(function(e){a.push(y(e.code,e.tplToken)),r.push(E(e.code))}),f&&(r.push(m+"=''"),r.push(p+"("+b+","+c+","+g+")")),r.push("return "+m),r.push("}");var T=r.join("\n");try{var O=new Function(l,w,"return "+T)(s,e);return O.mappings=a,O.sourcesContent=[i],O}catch(P){for(var $=0,j=0,_=0,S=void 0;$<n.length;){var C=n[$];if(!this.checkExpression(C.code)){j=C.tplToken.line,_=C.tplToken.start,S=C.code;break}$++}throw{name:"CompileError",path:o,message:P.message,line:j+1,column:_+1,source:i,generated:S,stack:P.stack}}}}]),e}();E.CONSTS={DATA:c,IMPORTS:l,PRINT:f,INCLUDE:p,EXTEND:h,BLOCK:d,OPTIONS:w,OUT:m,LINE:v,BLOCKS:g,SLICE:y,FROM:b,ESCAPE:"$escape",EACH:"$each"},e.exports=E},function(e,t,n){"use strict";var r=n(8),i=n(1)["default"],o=n(1).matchToToken,s=function(e){return e.match(i).map(function(e){return i.lastIndex=0,o(i.exec(e))}).map(function(e){return"name"===e.type&&r(e.value)&&(e.type="keyword"),e})};e.exports=s},function(e,t,n){"use strict";var r={"abstract":!0,await:!0,"boolean":!0,"break":!0,"byte":!0,"case":!0,"catch":!0,"char":!0,"class":!0,"const":!0,"continue":!0,"debugger":!0,"default":!0,"delete":!0,"do":!0,"double":!0,"else":!0,"enum":!0,"export":!0,"extends":!0,"false":!0,"final":!0,"finally":!0,"float":!0,"for":!0,"function":!0,"goto":!0,"if":!0,"implements":!0,"import":!0,"in":!0,"instanceof":!0,"int":!0,"interface":!0,"let":!0,"long":!0,"native":!0,"new":!0,"null":!0,"package":!0,"private":!0,"protected":!0,"public":!0,"return":!0,"short":!0,"static":!0,"super":!0,"switch":!0,"synchronized":!0,"this":!0,"throw":!0,"transient":!0,"true":!0,"try":!0,"typeof":!0,"var":!0,"void":!0,"volatile":!0,"while":!0,"with":!0,"yield":!0};e.exports=function(e){return r.hasOwnProperty(e)}},function(e,t,n){"use strict";function r(e){var t=new String(e.value);return t.line=e.line,t.start=e.start,t.end=e.end,t}function i(e,t,n){this.type=e,this.value=t,this.script=null,n?(this.line=n.line+n.value.split(/\n/).length-1,this.line===n.line?this.start=n.end:this.start=n.value.length-n.value.lastIndexOf("\n")-1):(this.line=0,this.start=0),this.end=this.start+this.value.length}var o=function(e,t){for(var n=arguments.length>2&&arguments[2]!==undefined?arguments[2]:{},o=[new i("string",e)],s=0;s<t.length;s++)for(var a=t[s],u=a.test.ignoreCase?"ig":"g",c=new RegExp(a.test.source,u),l=0;l<o.length;l++){var f=o[l],p=o[l-1];if("string"===f.type){for(var h=void 0,d=0,m=[],v=f.value;null!==(h=c.exec(v));)h.index>d&&(p=new i("string",v.slice(d,h.index),p),m.push(p)),p=new i("expression",h[0],p),h[0]=r(p),p.script=a.use.apply(n,h),m.push(p),d=h.index+h[0].length;d<v.length&&(p=new i("string",v.slice(d),p),m.push(p)),o.splice.apply(o,[l,1].concat(m)),l+=m.length-1}}return o};o.TYPE_STRING="string",o.TYPE_EXPRESSION="expression",o.TYPE_RAW="raw",o.TYPE_ESCAPE="escape",e.exports=o},function(e,t,n){"use strict";(function(t){function n(e){return"string"!=typeof e&&(e=e===undefined||null===e?"":"function"==typeof e?n(e.call(e)):JSON.stringify(e)),e}function r(e){var t=""+e,n=s.exec(t);if(!n)return e;var r="",i=void 0,o=void 0,a=void 0;for(i=n.index,o=0;i<t.length;i++){switch(t.charCodeAt(i)){case 34:a=""";break;case 38:a="&";break;case 39:a="'";break;case 60:a="<";break;case 62:a=">";break;default:continue}o!==i&&(r+=t.substring(o,i)),o=i+1,r+=a}return o!==i?r+t.substring(o,i):r}/*! art-template@runtime | https://github.com/aui/art-template */
var i="undefined"!=typeof self?self:"undefined"!=typeof window?window:void 0!==t?t:{},o=Object.create(i),s=/["&'<>]/;o.$escape=function(e){return r(n(e))},o.$each=function(e,t){if(Array.isArray(e))for(var n=0,r=e.length;n<r;n++)t(e[n],n);else for(var i in e)t(e[i],i)},e.exports=o}).call(t,n(11))},function(e,t){var n;n=function(){return this}();try{n=n||Function("return this")()||(0,eval)("this")}catch(r){"object"==typeof window&&(n=window)}e.exports=n},function(e,t,n){"use strict";var r=Object.prototype.toString,i=function(e){return null===e?"Null":r.call(e).slice(8,-1)},o=function s(e,t){var n=void 0,r=i(e);if("Object"===r?n=Object.create(t||{}):"Array"===r&&(n=[].concat(t||[])),n){for(var o in e)Object.hasOwnProperty.call(e,o)&&(n[o]=s(e[o],n[o]));return n}return e};e.exports=o},function(e,t,n){"use strict";var r=function(e,t,r,i){var o=n(0);return i=i.$extend({filename:i.resolveFilename(e,i),bail:!0,source:null}),o(i)(t,r)};e.exports=r},function(e,t,n){"use strict";var r=function(e){console.error(e.name,e.message)};e.exports=r},function(e,t,n){"use strict";var r={__data:Object.create(null),set:function(e,t){this.__data[e]=t},get:function(e){return this.__data[e]},reset:function(){this.__data={}}};e.exports=r},function(e,t,n){"use strict";var r="undefined"==typeof window,i=function(e){if(r){return n(3).readFileSync(e,"utf8")}var t=document.getElementById(e);return t.value||t.innerHTML};e.exports=i},function(e,t,n){"use strict";var r={test:/{{([@#]?)[ \t]*(\/?)([\w\W]*?)[ \t]*}}/,use:function(e,t,n,i){var o=this,s=o.options,a=o.getEsTokens(i),u=a.map(function(e){return e.value}),c={},l=void 0,f=!!t&&"raw",p=n+u.shift(),h=function(t,n){console.warn((s.filename||"anonymous")+":"+(e.line+1)+":"+(e.start+1)+"\nTemplate upgrade: {{"+t+"}} -> {{"+n+"}}")};switch("#"===t&&h("#value","@value"),p){case"set":i="var "+u.join("").trim();break;case"if":i="if("+u.join("").trim()+"){";break;case"else":var d=u.indexOf("if");~d?(u.splice(0,d+1),i="}else if("+u.join("").trim()+"){"):i="}else{";break;case"/if":i="}";break;case"each":l=r._split(a),l.shift(),"as"===l[1]&&(h("each object as value index","each object value index"),l.splice(1,1));i="$each("+(l[0]||"$data")+",function("+(l[1]||"$value")+","+(l[2]||"$index")+"){";break;case"/each":i="})";break;case"block":l=r._split(a),l.shift(),i="block("+l.join(",").trim()+",function(){";break;case"/block":i="})";break;case"echo":p="print",h("echo value","value");case"print":case"include":case"extend":if(0!==u.join("").trim().indexOf("(")){l=r._split(a),l.shift(),i=p+"("+l.join(",")+")";break}default:if(~u.indexOf("|")){var m=a.reduce(function(e,t){var n=t.value,r=t.type;return"|"===n?e.push([]):"whitespace"!==r&&"comment"!==r&&(e.length||e.push([]),":"===n&&1===e[e.length-1].length?h("value | filter: argv","value | filter argv"):e[e.length-1].push(t)),e},[]).map(function(e){return r._split(e)});i=m.reduce(function(e,t){var n=t.shift();return t.unshift(e),"$imports."+n+"("+t.join(",")+")"},m.shift().join(" ").trim())}f=f||"escape"}return c.code=i,c.output=f,c},_split:function(e){e=e.filter(function(e){var t=e.type;return"whitespace"!==t&&"comment"!==t});for(var t=0,n=e.shift(),r=/\]|\)/,i=[[n]];t<e.length;){var o=e[t];"punctuator"===o.type||"punctuator"===n.type&&!r.test(n.value)?i[i.length-1].push(o):i.push([o]),n=o,t++}return i.map(function(e){return e.map(function(e){return e.value}).join("")})}};e.exports=r},function(e,t,n){"use strict";var r={test:/<%(#?)((?:==|=#|[=-])?)[ \t]*([\w\W]*?)[ \t]*(-?)%>/,use:function(e,t,n,r){return n={"-":"raw","=":"escape","":!1,"==":"raw","=#":"raw"}[n],t&&(r="/*"+r+"*/",n=!1),{code:r,output:n}}};e.exports=r},function(e,t,n){"use strict";function r(e){if(Array.isArray(e)){for(var t=0,n=Array(e.length);t<e.length;t++)n[t]=e[t];return n}return Array.from(e)}var i="undefined"==typeof window,o=function(e,t){if(i){var o,s=n(20).minify,a=t.htmlMinifierOptions,u=t.rules.map(function(e){return e.test});(o=a.ignoreCustomFragments).push.apply(o,r(u)),e=s(e,a)}return e};e.exports=o},function(e,t){!function(e){e.noop=function(){}}("object"==typeof e&&"object"==typeof e.exports?e.exports:window)},function(e,t,n){"use strict";var r="undefined"==typeof window,i=/^\.+\//,o=function(e,t){if(r){var o=n(3),s=t.root,a=t.extname;if(i.test(e)){var u=t.filename,c=!u||e===u,l=c?s:o.dirname(u);e=o.resolve(l,e)}else e=o.resolve(s,e);o.extname(e)||(e+=a)}return e};e.exports=o},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function i(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function o(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}function s(e){var t=e.name,n=e.source,r=e.path,i=e.line,o=e.column,s=e.generated,a=e.message;if(!n)return a;var u=n.split(/\n/),c=Math.max(i-3,0),l=Math.min(u.length,i+3),f=u.slice(c,l).map(function(e,t){var n=t+c+1;return(n===i?" >> ":" ")+n+"| "+e}).join("\n");return(r||"anonymous")+":"+i+":"+o+"\n"+f+"\n\n"+t+": "+a+(s?"\n generated: "+s:"")}var a=function(e){function t(e){r(this,t);var n=i(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e.message));return n.name="TemplateError",n.message=s(e),Error.captureStackTrace&&Error.captureStackTrace(n,n.constructor),n}return o(t,e),t}(Error);e.exports=a},function(e,t,n){"use strict";e.exports=n(2)}])});
- 模板引擎在客户端中的使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!--将模板引擎的库文件引入到当前页面-->
<script src="./js/template-web.js"></script>
</head>
<body>
<div id="container"></div>
<!--由于客户端不具备文件读取的能力,客户端模板不是一个单独文件,而是当前html文件的代码片断,这个代码片断要包裹在script中-->
<!--准备art-template模板-->
<script type="text/html" id="tpl">
<h1>{{username}} {{age}}</h1>
</script>
<script type="text/javascript">
// 告诉模板引擎将那个数据和哪个模板进行拼接
// 1) 模板id 2) 数据 对象类型
// 当前的模板和数据进行拼接
// 方法的返回值就是拼接好的html字符串
var html = template('tpl', {username: 'zhangsan', age: 30});
// console.log(html); // 测试模板方法返回的数据
// 返回的拼接字符串显示到页面当中
document.getElementById('container').innerHTML = html;
</script>
</body>
</html>
2.4 案例:验证邮箱地址唯一性
<body>
<div class="container">
<div class="form-group">
<label>邮箱地址</label>
<input type="email" class="form-control" placeholder="请输入邮箱地址" id="email">
</div>
<!--错误 bg-danger 正确 bg-success-->
<p id="info"></p>
</div>
<script src="ajax.js"></script>
<script>
// 获取页面中的元素
var emailInp = document.getElementById('email');
var info = document.getElementById('info');
// 文本框失去焦点
emailInp.onblur = function() {};
// 获取用户输入的邮箱地址
var email = this.value;
// 验证邮箱地址的正则表达式
var reg = '^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)+$';
// 如果用户输入的邮箱地址不符合规则
if (!reg.test(email)) {
// 用户提示
info.innerHTML = '请输入符合规则的邮箱地址';
// 提示信息显示为错误提示
info.className = 'bg-danger';
// 阻止程序向下执行
return;
}
// 向服务器发送请求
ajax({
url: 'http://localhost:3000/verifyEmailAdress',
data: {
email: email,
},
success: function(result) {
console.log(result);
// 信息显示在页面中
info.innerHTML = result.message;
info.className = 'bg-success';
},
error: function(result) {
console.log(result);
info.innerHTML = result.message;
info.className = 'bg-danger';
}
});
</script>
</body>
2.5 案例:搜索框内容自动提示
<body>
<div class="container">
<div class="form-group">
<input type="text" class="form-control" placeholder="请输入搜索关键字" id="search">
<ul class="list-group" id="list-box">
</ul>
</div>
<p id="info"></p>
</div>
<script src="ajax.js"></script>
<script src="template-web.js"></script>
<script type="text/html" id="tpl">
<!--循环拼接字符串的数组,使用模板的循环语法-->
{{each result}}
<li class="list-group-item">{{$value}}</li>
{{/each}}
</script>
<script>
// 获取搜索框
var searchInp = document.getElementById('search');
// 获取提示文字的存放容器
var listBox = document.getElementById('list-box');
// 存储定时器的变量
var timer = null;
// 当用户在文本框中输入的时候触发
searchInp.oninput = function() {
// 获取用户输入的内容
var key = this.value;
// 开启定时器,让请求延迟发送
timer = setTimeout(function() {
// 清除上一次开启的定时器
clearTimeout(timer);
// 如果用户没有在搜索框中输入内容
if (key.trim().length == 0) {
listBox.style.display = 'none';
return;
}
// 向服务器发送请求
// 向服务器索取和用户输入关键字相关的内容
ajax({
url: 'http://localhost:3000/searchAutoPrompt',
data: {
key: key
},
success: function(result) {
// 使用模板引擎拼接字符串
var html = template('tpl', {result: result});
// 将拼接好的字符串显示在页面中
listBox.innerHTML = html;
// 显示容器
listBox.style.display = 'block';
}
});
}, 800);
}
</script>
</body>
2.6 案例:省市区三级联动
<body>
<div class="container">
<div class="form-inline">
<div class="form-group">
<select class="form-control" id="province">
<option>请选择省份</option>
</select>
</div>
<div class="form-group">
<select class="form-control" id="city">
<option>请选择城市</option>
</select>
</div>
<div class="form-group">
<select class="form-control" id="area">
<option>请选择县城</option>
</select>
</div>
</div>
</div>
<script src="ajax.js"></script>
<script src="template-web.js"></script>
// 省份模板
<script type="text/html" id="provinceTpl">
<option>请选择省份</option>
{{each province}}
<option value="{{$value.id}}">"{{$value.name}}"</option>
{{/each}}
</script>
// 城市模板
<script type="text/html" id="cityTpl">
<option>请选择城市</option>
{{each city}}
<option value="{{$value.id}}">"{{$value.name}}"</option>
{{/each}}
</script>
// 县城模板
<script type="text/html" id="areaTpl">
<option>请选择城市</option>
{{each area}}
<option value="{{$value.id}}">"{{$value.name}}"</option>
{{/each}}
</script>
<script>
// 获取省市区下拉框元素
var province = document.getElementById('province');
var city = document.getElementById('city');
var area = document.getElementById('area');
// 获取省份信息
ajax({
url: 'http://localhost:3000/province',
success: function(data) {
// 将服务器端返回的数据和html进行拼接
var html = template('provinceTpl', {province: data});
// 将拼接好的html字符串显示在页面中
province.innerHTML = html;
}
});
// 为省份的下拉框添加值改变事件
province.onchange = function() {
// 获取省份id
var pid = this.value;
// 清空县城下拉框中的数据
var html = template('areaTpl', {area: []});
area.innerHTML = html;
// 根据省份id获取城市信息
ajax({
url: '/cities',
data: {
id: pid
},
success: function(data) {
var html = template('cityTpl', {city: data});
}
});
};
// 为城市的下拉框添加值该表事件
city.onchange = function() {
// 获取城市id
var cid = this.value();
// 根据城市id获取县城信息
ajax({
url: '/areas',
data: {
id: cid
},
success: function(data) {
var html = template('areaTpl', {area: data});
area.innerHTML = html;
}
});
};
</script>
</body>
3、FormData
3.1 FormData对象的作用
3.2 FormData对象的使用
3.3 FormData对象的实例方法
<body>
<!--创建普通的html表单-->
<form>
<input type="text" name="username">
<input type="password" name="password">
<input type="button" id="btn" value="提交">
</form>
<script type="text/javascript">
// 获取按钮
var btn = document.getElementById('btn');
// 获取表单
var form = document.getElementById('form');
// get('key')获取表单对象属性的值
console.log(formData.get('username'));
// set('key', 'value') 设置表单对象属性的值
// 如果表单属性存在,替换之前的属性值;表单的属性不存在,将会创建表单的属性
formData.set('username', 'lisi');
formData.append('username', 'lisi4');
// delete('key') 删除表单对应的属性值
formData.delete('password');
// 为按钮添加点击事件
btn.onclick = function() {
// 将普通的html表单转换为表单对象
var formData = new FormData(form);
// 创建Ajax对象
var xhr = new XMLHttpRequest();
// 配置Ajax对象
xhr.open('post', 'http://localhost:3000/formData');
// 发送ajax请求
xhr.send(formData);
// 监听xhr对象下面的onload事件
xhr.onload = function() {
// http状态码进行判断
if (xhr.status == 200) {
console.log(xhr.responseText);
}
}
// 创建空的表单对象
var f = new FormData();
f.append('sex', '男');
console.log(f.get('sex'));
}
</script>
</body>
3.4 FormData 二进制文件上传
3.5 FormData 文件上传进度展示
3.6 FormData 文件上传图片即时预览
<body>
<div class="container">
<div class="form-group">
<label>请选择文件</label>
<input type="file" id="file">
<div class="padding" id="box">
// 图片要在js中动态创建
<!--<img src="" class="img-rounded img-responsive">-->
</div>
<div class="progress">
<div class="progress-bar" style="width: 0%;" id="bar">0%</div>
</div>
</div>
</div>
<script type="text/javascript">
// 获取文件选择控件
var file = document.getElementById('file');
// 获取进度条元素
var bar = document.getElementById('bar');
// 获取图片容器
var box = document.getElementById('box');
// 为文件选择控件添加onchanges事件
// 在用户选择文件时触发
file.onchange = function() {
var formData = new FormData();
formData.append('attrName', this.files[0]);
// 创建ajax对象
var xhr = new XMLHttpRequest();
// 对ajax对象进行配置
xhr.open('post','http://localhost:3000/upload');
// 在文件上传的过程中=持续触发
xhr.upload.onprogress = function(e) {
// e.loaded 文件已经上传了多少
// e.total 上传文件的总大小
var result = (e.loaded / e.total) * 100 + '%';
// 设置进度条的宽度
bar.style.width = result;
// 将百分比显示在进度条中
bar.innerHTML = result;
}
// 发送ajax请求
xhr.send(formData);
// 监听服务器响应给客户端
xhr.onload = function() {
if (xhr.status == 200) {
var result = JSON.parse(xhr.responseText);
// 动态创建img表单
var img = document.createElement('img');
// 给图片标签设置src属性
img.src = result.path;
// 图片加载完成,触发onload事件
img.onload = function() {
// 将图片显示在页面中
box.appendChild(img);
};
}
};
}
</script>
</body>
4、同源政策
4.1 Ajax 请求限制
4.2 使用JSONP解决同源限制问题
4.3 JSONP代码优化
<body>
<button id="btn">点我发送请求</button>
// 必须写在前面,fn()函数才能被加载
<script>
function fn(data) {
console.log('客户端的fn函数被调用了');
console.log(data)
}
</script>
<!--将非同源服务器的请求地址写在script标签的src属性中-->
<!--由于动态创建了script,此处的script就不需要了-->
<!--<script src="http://localhost:3001/better?callback=fn"></script>-->
<script type="text/javascript">
// 获取按钮
var btn = document.getElementById('btn');
// btn.onclick = function() {
// // 创建script标签
// var script = document.createElement('script');
// // 设置src属性
// script.src = 'http://localhost:3001/better?callback=fn';
// // 将script标签追加到页面中
// document.body.appendChild(script);
// // 为script标签添加onload事件,解决script加载一次就不需要了,删除script标签,而且避免了重复添加script标签
// script.onload = function() {
// // 将body中的script标签删除掉
// document.body.removeChild(script);
// };
// };
btn.onclick = function () {
jsonp({
// 请求地址
url: 'http://localhost:3001/better?callback=fn',
data: {
name: 'lisi',
age: 30
},
success: function(data) {
console.log(123);
console.log(data)
}
});
}
// 封装jsonp函数
function jsonp(options) {
// 动态创建script标签
var script = document.createElement('script');
// 拼接字符串
var params = '';
for (var attr in options.data) {
params += '&' + attr + '=' + options.data[attr];
}
// 函数名不能为纯数字,解决函数名重复问题,导致后面的函数会覆盖前面的函数
var fnName = 'myJsonp' + Math.random().toString().replace('.','');
// 将success变成全局函数
window[fnName] = options.success;
// 为script标签添加src属性
script.src = options.url + '?callback=' + fnName + params;
// 将script标签追加到页面中
document.body.appendChild(script);
// 为script标签添加onload事件
script.onload = function() {
document.body.removeChild(script);
};
}
jsonp({
//请求地址
url: 'http://localhost:3001/better?callback=fn'
});
</script>
</body>
4.4 访问非同源数据 服务器端解决方案
4.5 cookie
4.6 withCredentials属性
<body>
<div class="container">
<form id="loginForm">
<div class="form-group">
<label>用户名</label>
<input type="text" name="username" class="form-control" placeholder="请输入用户名">
</div>
<div class="form-group">
<label>密码</label>
<input type="text" name="password" class="form-control" placeholder="请输入密码">
</div>
<input type="button" class="btn btn-default" value="登录" id="loginBtn">
<input type="button" class="btn btn-default" value="检测用户登录状态" id="checkLogin">
</form>
</div>
<script type="text/javascript">
// 获取按钮
var loginBtn = document.getElementById('loginBtn');
// 获取检测登录状态按钮
var checkLogin = document.getElementById('checkLogin');
// 获取登录表单
var loginForm = document.getElementById('loginForm');
// 为登录按钮添加点击事件
loginBtn.onclick = function() {
// 将html表单转换为formData表单对象
var formData = new FormData(loginForm);
// 创建ajax对象
var xhr = new XMLHttpRequest();
// 配置ajax对象
xhr.open('post', 'http://localhost:3001/login');
// 当发送跨域请求是,携带cookie信息
xhr.withCredentials = true;
// 发送请求并传递请求参数
xhr.send(formData);
// 监听服务器端给予的响应内容
xhr.onload = function() {
console.log(xhr.responseText);
};
};
checkLogin.onclick = function() {
var xhr = new XMLHttpRequest();
// 配置ajax对象
xhr.open('get', 'http://localhost:3001/checkLogin');
// 当发送跨域请求是,携带cookie信息
xhr.withCredentials = true;
// 发送请求并传递请求参数
xhr.send();
// 监听服务器端给予的响应内容
xhr.onload = function() {
console.log(xhr.responseText);
};
};
</script>
</body>
5、$.ajax()
package com.test.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;
/**
* 基于Jquery的$.ajax方法发送异步请求
*/
@WebServlet("/ajax.do")
public class JqueryAjaxServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
PrintWriter pw = resp.getWriter();
pw.print("Hello");
pw.flush();
pw.close();
}
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<script src="js/jquery-3.6.0.js"></script>
<script>
function but() {
$.ajax({
type: "get",
url: "ajax.do",
success: function(result) {
$("#span").html(result);
}
});
}
</script>
</head>
<body>
<span id="span"></span>
<input type="button" value="ok" onclick="but()">
</body>
</html>
- $.ajax()在异步请求中提交数据
-
- 提交普通格式数据
- 提交普通格式数据
- 通过标准格式指定提交数据
- 通过 JavaScript 对象指定提交数据
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;
/**
* 在$.ajax() 方法中提交数据
*/
@WebServlet("/data.do")
public class DataServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String userid = req.getParameter("id");
String username = req.getParameter("name");
PrintWriter pw = resp.getWriter();
pw.print(userid + " " + username);
pw.flush();
pw.close();
}
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<script src="js/jquery-3.6.0.js"></script>
<script>
function but() {
var userid = $("#userid").val();
var username = $("#username").val();
$.ajax({
type: "get",
url: "data.do",
// 标准格式
// data: "id=" + userid + "&username=" + username,
// javascript对象
data: {
id: userid,
name: username
},
success: function(result) {
$("#span").html(result);
}
});
}
</script>
</head>
<body>
用户名: <input type="text" id="userid">
用户姓名:<input type="text" id="username">
<span id="span"></span>
<input type="button" value="ok" onclick="but()">
</body>
</html>
-
- 提交 JSON 格式数据
- 提交 JSON 格式数据
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;
/**
* 在$.ajax() 方法中传递JSON格式的数据
*/
@WebServlet("/data.do")
public class DataServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String s = req.getReader().readLine();
PrintWriter pw = resp.getWriter();
pw.print(s);
pw.flush();
pw.close();
}
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<script src="js/jquery-3.6.0.js"></script>
<script>
function but() {
var userid = $("#userid").val();
var username = $("#username").val();
$.ajax({
type: "post",
url: "data.do",
// JSON格式数据
data: JSON.stringify({
id: userid,
name: username
}),
success: function(result) {
$("#span").html(result);
}
});
}
</script>
</head>
<body>
用户名: <input type="text" id="userid">
用户姓名:<input type="text" id="username">
<span id="span"></span>
<input type="button" value="ok" onclick="but()">
</body>
</html>
- $.ajax()处理响应中的 JSON 格式数据
package com.test.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;
/**
* 提交JSON格式数据在页面中自动转换类型
*/
@WebServlet("/data.do")
public class DataServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("application/json");
String s = req.getReader().readLine();
PrintWriter pw = resp.getWriter();
pw.print(s);
pw.flush();
pw.close();
}
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<script src="js/jquery-3.6.0.js"></script>
<script>
function but() {
var userid = $("#userid").val();
var username = $("#username").val();
$.ajax({
type: "post",
url: "data.do",
dataType: "json",
// JSON格式数据
data: JSON.stringify({
id: userid,
name: username
}),
success: function(result) {
alert(result.id + " " + result.name)
$("#span").html(result);
}
});
}
</script>
</head>
<body>
用户名: <input type="text" id="userid">
用户姓名:<input type="text" id="username">
<span id="span"></span>
<input type="button" value="ok" onclick="but()">
</body>
</html>
5.1 $.ajax()方法概述
<body>
<button id="btn">发送请求</button>
<script src="./js/jquery.min.js"></script>
<script>
var params = {name: 'wangwu', age:30};
$('#btn').on('click', function () {
$.ajax({
// 请求方式
type: 'post',
// 请求地址
url: '/base',
beforeSend: function() {
alert('请求不会被发送');
// 请求不会被发送
return false;
},
data: JSON.stringify(params),
// 指定参数的格式类型
contentType: 'application/json',
// 请求成功以后函数被调用
success: function(response) {
// response为服务器返回的数据
// 会自动把字符串转换成json对象
console.log(response);
},
// 请求失败的时候调用
error: function(xhr) {
// xhr会存储一些关于错误的信息
console.log(xhr);
}
});
});
</script>
</body>
5.2 serialize方法
<body>
<form id="form">
<input type="text" name="username">
<input type="password" name="password">
<input type="submit" value="提交">
</form>
<script src="./js/jquery.min.js"></script>
<script type="text/javascript">
$('#form').on('submit', function() {
// 将表单内容拼接成字符串类型的参数
// var params = $('#form').serialize();
// console.log(params);
serialzeObject($(this));
// 阻止表单提交
return false;
});
// 将表单中用户输入的内容转换为对象类型
function serialzeObject(obj) {
// 处理结果对象
var result = {};
var params = obj.serializeArray();
// 循环params,将数组转化为对象类型
$.each(params, function(index, value) {
result[value.name] = value.value;
});
// 将处理的结果返回到函数外部
return result;
}
</script>
</body>
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;
import java.util.HashMap;
import java.util.Map;
@WebServlet("/data.do")
public class DataServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String userid = req.getParameter("id");
String username = req.getParameter("name");
Map<String,String> map = new HashMap<>();
map.put("userid", userid);
map.put("username",username);
String s = JsonUtils.objectToJson(map);
resp.setContentType("application/json");
PrintWriter pw = resp.getWriter();
pw.print(s);
pw.flush();
pw.close();
}
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<script src="js/jquery-3.6.0.js"></script>
<script>
function but() {
var param = $("#form").serialize();
$.ajax({
type: "get",
url: "data.do",
data: param,
success: function(result) {
$("#span").html(result);
}
});
}
</script>
</head>
<body>
<form id="form">
用户名: <input type="text" name="id" id="userid">
用户姓名:<input type="text" name="name" id="username">
</form>
<span id="span"></span>
<input type="button" value="ok" onclick="but()">
</body>
</html>
5.3 $.get()方法、$.post()方法
5.3.1 $.get()的使用
- 语法结构
$.get(url,function(result))
$.get(url,data,function(result)) - 通过标准格式指定提交数据
$.get(url,”name=value&name=value”,function(result)) - 通过JavaScript 对象指定提交数据
$.get(url,{userid:1,username:”oldlu”,…},function(result))
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<script src="js/jquery-3.6.0.js"></script>
<script>
function but() {
var userid = $("#userid").val();
var username = $("#username").val();
// 标准对象
$.get("data.do","id=" + userid + "&name=" + username,function(result) {
$("#span").html(result);
});
// Javascript格式类型数据
$.get("data.do", {id:userid, name:username}, function(result) {
$("#span").html(result);
});
}
</script>
</head>
<body>
用户名: <input type="text" id="userid">
用户姓名:<input type="text" id="username">
<span id="span"></span>
<input type="button" value="ok" onclick="but()">
</body>
</html>
5.3.2 $.post()的使用
- 语法结构
$.post(url,function(result))
$.post(url,data,function(result)) - 通过标准格式指定提交数据
$.post(url,”name=value&name=value”,function(result)) - 通过JavaScript 对象指定提交数据
$.post(url,{userid:1,username:”oldlu”,…},function(result))
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<script src="js/jquery-3.6.0.js"></script>
<script>
function but() {
var userid = $("#userid").val();
var username = $("#username").val();
// 标准对象
// $.post("data.do","id=" + userid + "&name=" + username,function(result) {
// $("#span").html(result);
// });
// JavaScript格式类型数据
$.post("data.do", {id:userid, name:username}, function(result) {
$("#span").html(result);
});
}
</script>
</head>
<body>
用户名: <input type="text" id="userid">
用户姓名:<input type="text" id="username">
<span id="span"></span>
<input type="button" value="ok" onclick="but()">
</body>
</html>
5.3.3 $.getJSON()的使用
- 语法结构
$.getJSON(url,function(result))
$.getJSON(url,data,function(result)) - 通过标准格式指定提交数据
$.getJSON(url,”name=value&name=value”,function(result))
要求返回的数据格式必须是JSON 格式。 - 通过JavaScript 对象指定提交数据
$.getJSON(url,{userid:1,username:”oldlu”,…},function(result))
要求返回的数据格式必须是JSON 格式。
package com.test.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;
import java.util.HashMap;
import java.util.Map;
/**
* getJSON方法传递数据并返回JSON个数数据
*/
@WebServlet("/data.do")
public class DataServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String userid = req.getParameter("id");
String username = req.getParameter("name");
Map<String,String> map = new HashMap<>();
map.put("userid", userid);
map.put("username",username);
String s = JsonUtils.objectToJson(map);
resp.setContentType("application/json");
PrintWriter pw = resp.getWriter();
pw.print(s);
pw.flush();
pw.close();
}
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<script src="js/jquery-3.6.0.js"></script>
<script>
function but() {
var userid = $("#userid").val();
var username = $("#username").val();
$.getJSON("data.do", {id:userid, name:username},function(result) {
alert(result.userid + " " + result.username);
$("#span").html(result.userid + " " + result.username);
});
}
</script>
</head>
<body>
用户名: <input type="text" id="userid">
用户姓名:<input type="text" id="username">
<span id="span"></span>
<input type="button" value="ok" onclick="but()">
</body>
</html>
6、JQuery中Ajax全局事件
7、RESTful 风格的API
7、XML
7.1 XML DOM
<body>
<button id="btn">发送请求</button>
<div id="container"></div>
<script type="text/javascript">
var btn = document.getElementById('btn');
var container = document.getElementById('container');
btn.onclick = function() {
var xhr = new XMLHttpRequest();
xhr.open('get', '/xml');
xhr.send();
xhr.onload = function() {
// 获取服务端返回的XML数据
// console.log(xhr.responseXML);
var xmlDocument = xhr.responseXML;
var title = xmlDocument.getElementsByTagName('title')[0].innerHTML;
container.innerHTML = title;
};
}
</script>
</body>