原生AJAX
发送ajax请求的步骤
- 创建 XMLhttp Request 类型的对象
- 准备发送,打开与一个网址之间的连接
- 执行发送动作
- 指定 xhr 状态变化事件处理函数
// 1.创建一个 XMLHttpRequest 类型的对象 --- 相当于打开了一个浏览器
var xhr = new XMLHttpRequest();
// 2.打开一个与网址之间的连接 --- 相当于在地址栏输入网址
xhr.open("GET","https://jsonplaceholder.typicode.com/users");
// 3.通过连接发送一次请求 --- 相当于点击回车或者超链接
xhr.send(null);
// 4.指定 xhr 状态变化事件处理函数 --- 相当于处理网页呈现后的操作
xhr.onreadystatechange = function () {
// 通过判断 xhr 的 readyState ,确定此次请求是否完成
if (this.readyState === 4) {
console.log(this.responseText)
}
}
XMLHttpRequest 类型对象
// 1.创建一个 XMLHttpRequest 类型的对象
var xhr = null;
// 兼容写法
if (window.XMLHttpRequest) {
// 标准浏览器
xhr = new XMLHttpRequest();
} else {
// IE 6 浏览器
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
open() 方法开启请求
// 2.open() 方法开启请求
// xhr.open("GET","https://jsonplaceholder.typicode.com/users?id=1");
xhr.open("POST","https://jsonplaceholder.typicode.com/users");
setRequestHeader() 方法设置请求头
// 设置请求头
// 一般 get 方法不需要设置,而 post 方法必须设置
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
send() 方法发送请求
// 3.send() 方法发送一次请求
// 如果是 get 方法请求,不需要再 send 中传参数,它如果想传参数,直接写在网址上
// xhr.send(null);
xhr.send("name=harry&age=19");
readyState 属性
事件处理函数
- 一般我们都是在 readyState 值为 4 时,执行响应的后续逻辑。
xhr.onreadystatechange = function () {
// 通过判断 xhr 的 readyState ,确定此次请求是否完成
if (this.readyState === 4) {
console.log(this.responseText)
}
}
同步与异步
- xhr.open() 方法中第三个参数要求传入一个布尔值,其作用是设置此次请求是同步还是一步执行
- 默认是true,异步执行
- 若采用同步执行,参数设置为false即可
- ⚠️:如果同步执行,则代码会卡死在xhr.send() 这一步(解决方法:先注册 readystatechange 事件,再发送请求send())
// 2.打开一个与网址之间的连接
// 设置同步或异步
// xhr.open("GET","https://jsonplaceholder.typicode.com/users",true);
xhr.open("GET","https://jsonplaceholder.typicode.com/users",false);
// 如果设置了同步加载,程序会卡在 send 部分
xhr.onreadystatechange = function () {
// 通过判断 xhr 的 readyState ,确定此次请求是否完成
if (this.readyState === 4) {
console.log("请求成功")
}
}
// 3.通过连接发送一次请求
xhr.send(null);
// 4.指定 xhr 状态变化事件处理函数
// Ajax 后面的代码
console.log("After Ajax");
响应数据格式(json)
- 服务端采用json格式返回数据,客户端按照json格式解析数据
- json数据和js数据的互相转换
// json转js
JSON.parse(json字符串)
// js转json
JSON.stringfy(js对象)
JSON Server
- json-server 是一个 Node 模块,运行Express服务器,可以指定一个 json 文件作为 api 的数据源
- 我们可以使用 json-server 搭建一个web服务器
原生 AJAX get请求
var xhr = new XMLHttpRequest();
// 发送 GET 请求
xhr.open("GET", "http://localhost:3000/posts?id=1");
xhr.send(null);
xhr.onreadystatechange = function () {
if (this.readyState === 4) {
console.log(this.responseText);
}
}
原生 AJAX post请求
var xhr = new XMLHttpRequest();
// post 请求
xhr.open("POST","http://localhost:3000/posts");
// 设置请求头
xhr.setRequestHeader("Content-Type","application/json");
xhr.send(JSON.stringify({
"title": "test",
"author": "zm"
}));
xhr.onreadystatechange = function () {
if (this.readyState === 4) {
console.log(this.responseText);
}
}
jQuery 中的 AJAX
$.ajax()
// $.ajax()
// 参数是一个 配置的对象
console.log($.ajax())
$.ajax({
url: "http://localhost:3000/posts",
type: "get",
dataType: "json",
data: {"id": 2},
// send 之前执行
beforeSend: function (xhr) {
console.log("before send");
console.log(xhr);
},
// 成功后执行
success: function (data) {
console.log(data);
},
// 失败了执行
error: function (xhr) {
console.log(xhr);
},
// 完成后执行,不管失败还是成功
complete: function (xhr) {
console.log(xhr);
}
});
$.get()
// 发送 get 请求
// $.ajax({
// url: "http://localhost:3000/comments",
// type: "get",
// dataType: "json",
// data: {"id": 2},
// success: function (data) {
// console.log(data);
// }
// })
// 化简后的方法直接发送 get 请求
$.get("http://localhost:3000/comments", {"id": 1}, function (data) {
console.log(data);
})
$.post()
// 发送 post 请求
// $.ajax({
// url: "http://localhost:3000/comments",
// type: "post",
// dataType: "json",
// data: {"postId": 2, "content": "bad"},
// success: function (data) {
// console.log(data);
// }
// })
// $.post() 快捷方法发送请求
$.post("http://localhost:3000/comments", {"postId": 3, "content": "bad"},function (data) {
console.log(data);
})
其他请求
- put 更改
- delete 删除
- 参数写在url后方
// put 请求,更改数据
// $.ajax({
// url: "http://localhost:3000/comments/4",
// type: "put",
// dataType: "json",
// data: {"content": "good", "postId": 2},
// success: function (data) {
// console.log(data)
// }
// })
// delete 请求,删除数据
$.ajax({
url: "http://localhost:3000/comments/5",
type: "delete",
success: function (data) {
console.log(data)
}
})
jQuery 中其他 Ajax 方法
- $.ajaxSetup()
// ajaxSetup() 方法,设置默认的参数
$.ajaxSetup({
url: "http://localhost:3000/users",
type: "post",
success: function (data) {
console.log(data)
}
})
// 发送 ajax请求
$.ajax({
data: {"name": "zm", "age": 17, "class": 4}
})
$.ajax({
data: {"name": "oy", "age": 18, "class": 4}
})
Axios
- Axios 是目前应用最为广泛的 AJAX 封装库
Axios API
// axios 方法
axios({
url: "/comments",
method: "post",
baseURL: "http://localhost:3000",
headers: {
"Content-Type": "application/json"
},
timeout: 1000,
data: {
"postId": 3,
"content": "better"
}
}).then(function (res) {
// 正常请求的响应对象res
console.log(res.data)
}).catch(function (error) {
// 捕获错误
console.log(error)
})
全局默认配置
// 全局配置默认值
axios.defaults.baseURL = "http://localhost:3000";
// axios 方法
axios({
url: "/comments",
method: "get"
}).then(function (res) {
console.log(res.data)
}).catch(function (error) {
console.log(error)
})
axios 方法
// axios 方法 请求post
// axios("http://localhost:3000/posts",{
// method: "post",
// data: {
// "title": "json-server",
// "author": "typicode"
// }
// })
// .then(function (res) {
// console.log(res.data)
// })
// .catch(function (error) {
// console.log(error)
// })
// axios 方法 请求get,不传 method 参数,默认为get
axios("http://localhost:3000/posts",{
params: {
id: "1"
}
})
.then(function (res) {
console.log(res.data)
})
.catch(function (error) {
console.log(error)
})
axios 拦截器
// 使用拦截器,对请求进行拦截处理
axios.interceptors.request.use(function (config) {
// 可以代替之前的全局默认配置
config.params = {
id: 2
}
config.baseURL = "http://localhost:3000"
return config
})
// 对响应进行拦截
axios.interceptors.response.use(function (response) {
return response.data;
})
// axios 方法
axios("/posts")
.then(function (res) {
console.log(res)
})
.catch(function (error) {
console.log(error)
});
// 拦截器对下面的请求同样适用
// axios("/comments")
// .then(function (res) {
// console.log(res)
// })
快速请求方法
// get 请求
// axios.get("http://localhost:3000/users?id=2")
// .then(function (res) {
// console.log(res.data)
// })
// axios.get("http://localhost:3000/users",{
// params: {
// id: 3
// }
// })
// .then(function (res) {
// console.log(res.data)
// })
// post 请求 ,添加数据
axios.post("http://localhost:3000/users",{
"name": "nancy",
"age": 19,
"class": 2
})
.then(function (res) {
console.log(res.data)
})
XMLHttpRequest 2.0
onload / onprogress
- xhr.onload 事件:只在请求完成时触发(readyState == 4)
- xhr.onprogress 事件:只在请求进行中触发(readyState == 3)
response 属性
- 以对象的形式表述响应体,其类型取决于 responseType 的值
- responseType 要在调用 open() 初始化请求之后,在调用 send() 发送请求到服务器之前 设置方可生效
var xhr = new XMLHttpRequest();
xhr.open("GET", "http://localhost:3000/posts");
xhr.responseType = "json";
xhr.onload = function () {
console.log(this.response);
}
xhr.send(null);
跨域
同源策略
- 同源策略是浏览器的一种安全策略,所谓同源是指域名,协议,端口完全相同
- 在同源策略下,只有同源的地址才可以相互通过 AJAX 的方式请求。
- 同源或者不同源说的是两个地址之间的关系,不同源地址之间请求我们称之为跨域请求
跨域解决方案 - JSONP
- 通过 script 标签发送跨域请求
- 借助 script 标签请求服务端的一个地址
- 地址返回一段带有某个全局函数调用的js脚本
- 在调用函数中,原本需要返回客户的数据,通过参数传递给这个函数
- 客户端的函数中的参数,就是服务端想要返回给客户端的数据
- ⚠️:JSONP 只能发送get请求
jQuery 中对 JSONP 的支持
- jQuery 中使用 JSONP 就是将 dataType 设置为jsonp
$(".btn").click(function () {
// 发送跨域的 ajax 请求
$.ajax({
url: "https://www.baidu.com/sugrec?pre=1&p=3&ie=utf-8&json=1&prod=pc&from=pc_web",
type: "GET",
dataType: "jsonp",
jsonp: "cb", //这条属性可以设置回调函数的参数名称(必须与后台接口的回调函数参数名保持一致)
jsonpCallback: "abc", //jQ 自动分配的回调函数的名称进行重命名
data: {"wd": "ajax"},
success: function (data) {
console.log(data)
}
})
})
跨域解决方案 - CORS
- 跨域资源共享
- 不需要客户端做出任何变化,只是在被请求的服务端响应时添加一个Access-Control-Allow-Origin 的响应头,表示这个资源是否允许指定域请求
模版引擎
- 减少字符串拼接
- 在模版里面解析json,然后跟html 内容拼接,性能会更好
artTemplate
常用语法:
- <% 与 %> 符号包裹起来的语句则为模板的逻辑表达式
- <%= content %>为输出表达式
<!-- 1、引入jquery -->
<script src="js/jquery-1.12.4.min.js"></script>
<!-- 2、引入模板的文件 -->
<script src="js/template-native.js"></script>
<script id = "tem" type = "text/html">
<% for (var i = 0; i < 3; i++) { %>
<div>这是模版引擎<%= i %></div>
<div>这是模版引擎<%= name %></div>
<% } %>
</script>
</head>
<body>
<div class="box"></div>
<script>
$(".box").html(template("tem", {name: "zm"}))
</script>
</body>