【三】Ajax与异步编程之数据传输格式ajax
【1】什么是ajax
-
ajax,一般中文称之为:"阿贾克斯",是英文 “Async Javascript And Xml”的简写
- 译作:异步js和xml传输数据技术。
-
ajax的作用:
- ajax可以让js代替浏览器向服务端程序发送
http
请求,与服务端进行数据通信,在用户不知道的情况下操作数据和信息,从而实现页面局部刷新数据/无刷新更新数据。
- ajax可以让js代替浏览器向服务端程序发送
-
所以开发中ajax是很常用的技术,主要用于操作服务端提供的
数据接口
,从而实现网站的前后端分离
。 -
ajax技术的原理是实例化js的全局对象XMLHttpRequest,使用此对象提供的内置方法就可以与服务端进行http数据通信。
【2】数据接口
-
数据接口,也叫api接口,表示
服务端提供
操作数据/功能的url地址给客户端使用。 -
客户端通过发起请求向服务端提供的url地址申请操作数据【操作一般为:增删查改】
-
同时在工作中,大部分数据接口都不是手写,而是通过函数库/框架来自动生成的。
【3】前后端分离
-
在开发Web应用中,有两种应用模式:
-
前后端分离
- 前后端不分离
【4】基本使用
- ajax的使用必须与服务端程序配合使用
- 但是开发中我们对于ajax请求的数据,不仅仅可以是自己写的服务端代码,也可以是别人写好的数据接口进行调用。
- 原生js提供了不同的方式,允许前端开发者调用ajax。编写代码获取接口提供的数据:
方式1,基于XMLHttpRequest,实现ajax1.0
- 代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.data-table{
border-collapse: collapse;
width: 800px;
display: none;
}
.data-table td, .data-table th{
font-weight: normal;
border:1px solid red;
text-align: center;
width: 200px;
}
</style>
</head>
<body>
<input type="text" name="city" value="北京" placeholder="请输入一个国内的城市名称"><button>获取天气</button>
<table class="data-table">
<tr>
<th>日期</th>
<th>类型</th>
<th>风力</th>
<th>温度</th>
</tr>
</table>
</body>
<script>
var btn = document.querySelector("button")
var city = document.querySelector('input[name="city"]')
let data = document.querySelector(".data-table")
let old_conent = data.innerHTML // 原来的内容
btn.addEventListener("click", get_weather)
function get_weather(){
// 原生js的ajax: 基于XMLHttpRequest实现ajax1.0版本,有5个步骤
// 1. 创建ajax对象
var xhr = new XMLHttpRequest()
// console.log(xhr.readyState) // 0
// 2. 打开网络请求
// 参数1:method,http请求,默认XMLHttpRequest只实现了get与post请求
// 参数2:url,请求的资源路径,可以携带查询字符串
xhr.open("get", `http://wthrcdn.etouch.cn/weather_mini?city=${city.value}`)
// console.log(xhr.readyState) // 1
// 3. 发送网络请求
// 参数1:可选参数,如果是post请求,则填写请求体
// 请求体必须按查询字符串格式编写,属性=值&属性=值&属性=值.....
xhr.send()
// 4. 监听http通信状态
xhr.onreadystatechange = ()=>{
// 4.1 判断ajax的状态
/**
* readyState属性表示ajax的使用状态
* 0 表示刚创建ajax对象,还没有创建http网络请求
* 1 表示ajax对象已经创建http网络请求,但是还没有发送请求
* 2 表示ajax已经发送了http请求,但是服务端还没有接收到请求
* 3 表示服务端已经接收到客户端的http请求,但是没有处理完成
* 4 表示服务端已经处理完成客户端的http请求,并把处理结果返回给客户端了
*/
// 5. 判断xhr执行状态已经执行完成,并且http响应状态码是200才获取服务端的数据
if(xhr.readyState === 4){
if(xhr.status === 200){
// console.log(xhr.response) // 获取原生的响应数据[例如图片,音频等]
// console.log(xhr.responseText) // 获取纯文本格式数据
// console.log(xhr.responseXML) // 获取xml格式的数据
let response = JSON.parse(xhr.response)
console.log(response)
data.style.display = "block"
data.innerHTML = old_conent
console.log(response.data.forecast)
for (let info of response.data.forecast) {
data.innerHTML+=`<tr>
<td>${info.date}</td>
<td>${info.type}</td>
<td>${info.fengxiang} ${info.fengli.replace(/<!\[CDATA\[(.*?)\]\]>/,"$1")}</td>
<td>${info.low} ~ ${info.high}</td>
</tr>`
}
}
}
}
}
</script>
</html>
方式2:使用fetch全局方法实现ajax2.0
- 内置本质上就是XMLHttpRequest与Promise(ES6,es2015)来封装的一个函数
fetch使用文档:https://developer.mozilla.org/zh-CN/docs/Web/API/fetch
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.data-table{
border-collapse: collapse;
width: 800px;
display: none;
}
.data-table td, .data-table th{
font-weight: normal;
border:1px solid red;
text-align: center;
width: 200px;
}
</style>
</head>
<body>
<input type="text" name="city" value="北京" placeholder="请输入一个国内的城市名称"><button>获取天气</button>
<table class="data-table">
<tr>
<th>日期</th>
<th>类型</th>
<th>风力</th>
<th>温度</th>
</tr>
</table>
</body>
<script>
var btn = document.querySelector("button")
var city = document.querySelector('input[name="city"]')
let data = document.querySelector(".data-table")
let old_conent = data.innerHTML // 原来的内容
btn.addEventListener("click", get_weather)
function get_weather(){
// ajax2.0
// 基于fetch全局方法来实现
// fetch使用方式1:
// 参数1:Request对象
// fetch使用方式2:
// 参数1:字符串格式的url地址,
// 参数2:Request对象
// 返回值:Promise回调对象
fetch(`http://wthrcdn.etouch.cn/weather_mini?city=${city.value}`, {
method: "GET",
mode: 'cors',
}).then(response => { // 此处可以简写成 then(res=>res.json())
// 如果要接收来自服务端的json数据,则先要使用return response.json()来处理
// 如果要接收来自服务端的纯文本数据,则先要使用return response.text()来处理
// 如果要接收来自服务端的二进制数据,则先要使用return response.blob()来处理
return response.json()
})
.then(response => {
// 显示表格
data.style.display = "block"
data.innerHTML = old_conent
for (let info of response.data.forecast) {
data.innerHTML += `
<tr>
<td>${info.date}</td>
<td>${info.type}</td>
<td>${info.fengxiang} ${info.fengli.replace(/<!\[CDATA\[(.*?)\]\]>/, "$1")}</td>
<td>${info.low} ~ ${info.high}</td>
</tr>
`
}
}).catch((err) => {
// 如果ajax请求失败,或者then方法中的匿名函数中有代码异常,则自动执行catch方法
console.log("错误:", err);
// 如果要转换处理来自服务端的异常错误
console.log("来自服务端的错误:", err.response);
});
}
</script>
</html>
- 当然,所有的ajax都可以访问别人服务端提供的数据,也可以访问自己的服务端提供的数据。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<button class="btn1">点击获取服务端的数据1</button>
<button class="btn2">点击获取服务端的数据2</button>
<button class="btn3">点击获取服务端的数据3</button>
<script>
var btn1 = document.querySelector(".btn1")
var btn2 = document.querySelector(".btn2")
var btn3 = document.querySelector(".btn3")
btn1.onclick = function(){
fetch("http://127.0.0.1:8000/",{
method: "get",
mode: "cors",
}).then(response=>{
console.log(response.text());
})
}
btn2.onclick = function(){
fetch("http://127.0.0.1:8000/",{
method: "post",
mode: "cors",
headers:{
"Content-Type": "application/json",
},
body: JSON.stringify({'name': 'abc'}) // 发送json数据到服务端
}).then(response=>{
console.log(response.text());
})
}
btn3.onclick = function(){
fetch("http://127.0.0.1:8000/xiaohong",{
method: "put",
mode: "cors",
}).then(response=>{
console.log(response.json());
})
}
</script>
</body>
</html>
- 点击按钮以后的效果: