Ajax
1. 同步与异步
以前端请求,后端响应为例
- 同步: 前端发请求, 必须等到后端响应完成,才允许发送另一个请求
- 异步: 前端发请求后不等待后端响应结果继续执行,后端响应完成通过事件通知前端处理
异步最常用的处理形式就是回调函数
2. XMLHttpRequest 对象
XMLHttpRequest
是浏览器提供的,处理异步请求的宿主对象,而非 JS 内置对象- 基本流程:
- 创建请求对象:
new XMLHttpRequest()
- 监听请求回调:
onreadystatechange
- 初始化请求参数:
open(请求类型,请求地址,是否异步)
- 发送请求:
send()
- 如果是
POST
请求,以上步骤略有不同
- 创建请求对象:
new XMLHttpRequest()
- 监听请求回调:
onreadystatechange()
- 初始化请求参数:
open(请求类型,请求地址,是否异步)
- 设置请求头:
setRequestHeader()
- 准备请求参数: 可选
var data = ...
- 发送请求:
send(data)
3. GET 请求
- 服务器: 返回
JSON
- 前端:
JSON.parse()
解析 JSON 字符串
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Ajax -GET</title>
</head>
<body>
<script>
// - `XMLHttpRequest`是浏览器提供的,处理异步请求的宿主对象,而非 JS 内置对象
// - 基本流程:
// 1. 创建请求对象: `new XMLHttpRequest()`
var xhr = new XMLHttpRequest();
// 2. 监听请求回调: `onreadystatechange`
xhr.onreadystatechange =function(){
// status返回状态有200:ok,403:Forbidden,404:Not Found;
if(xhr.readyState === 4 && xhr.status === 200){
// 响应的数据存储在responseXML中
console.log(xhr.responseText);
}
};
// 3. 初始化请求参数: `open(请求类型,请求地址,是否异步)`
xhr.open("GET","test1.php",true);
// 4. 发送请求: `send()`
xhr.send(null);
</script>
</body>
</html>
<?php
$user['name'] = 'admin';
$user['email'] = 'admin@qq.com';
// 将数组转为json字符串, 不能用retrun, 必须用打印语句,如echo
echo json_encode($user);
4. POST 请求
- 前端: 发送
JSON
后端:
json 数据以表单数据类型发送,可
$_POST
接收<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Ajax-POST</title>
</head>
<body>
<script>
// - `XMLHttpRequest`是浏览器提供的,处理异步请求的宿主对象,而非 JS 内置对象
// - 基本流程:
// 1. 创建请求对象: `new XMLHttpRequest()`
var xhr =new XMLHttpRequest();
// 2. 监听请求回调: `onreadystatechange`
xhr.onreadystatechange = function () {
if(xhr.readyState === 4 && xhr.status === 200){
console.log(xhr.responseText);
}
};
// 3. 初始化请求参数: `open(请求类型,请求地址,是否异步)`
xhr.open('POST','test2.php',true);
// 4. 设置请求头,模拟表单类型的数组进行发送,application/x-www-form-urlencoded默认
xhr.setRequestHeader("content-type","application/x-www-form-urlencoded");
var user ={
email :"admin@qq.com",
password : "admin",
};
// js对象转为JSON字符串
var date = JSON.stringify(user)
xhr.send(date);
</script>
</body>
</html>
<?php
// print_r($_POST);
// 转化为字符串
$data = key($_POST);
echo $data;
// 将$data转为php可处理数据
$user =json_decode($data);
print_r($user);
// 转为数组方式
$user =json_decode($data,true);
print_r($user);
-
- json 数组就是以 JSON 发送,
php://input
流文件方式接收
- json 数组就是以 JSON 发送,
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Ajax-POST2</title>
</head>
<body>
<script>
var xhr = new XMLHttpRequest();
xhr.onreadystatechange =function(){
if(xhr.readyState === 4 && xhr.status === 200){
console.log(xhr.responseText);
}
};
xhr.open("POST","test3.php",true);
xhr.setRequestHeader("content-type","application/json;charset=utf-8");
var user = {
email : "admin@qq.com",
password :"admin",
};
var data = JSON.stringify(user);
xhr.send(data);
</script>
</body>
</html>
<?php
// print_r($_POST);
// 使用php://input来接收数据流
// file_get_contents将数据流改为文件流
$data= file_get_contents('php://input');
$user = json_decode($data);
print_r($user);
$user =json_decode($data,true);
print_r($user);
5. FormData
- 可直接序列化表单数据
- 可直接被 Ajax 识别,所以可以不设置请求头
- 除了表单数据外,也可用于普通数据
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<p>登录</p>
<form action="" method="POST" onsubmit="return false">
<input type="email" name="email" placeholder="ee@qq.com" required autofocus>
<input type="password" name="password" placeholder="****" required >
<button>提交</button>
</form>
<script>
// 获取表单和按钮
var form = document.querySelector("form");
var btn = document.querySelector("form button");
// 点击事件,进行Ajax请求
btn.onclick = function(){
// 创建请求对象:`new XMLHttpRequest()`
var xhr = new XMLHttpRequest();
// 2. 监听请求回调: `onreadystatechange`
xhr.onreadystatechange =function(){
if(xhr.readyState === 4 && xhr.status === 200){
console.log(xhr.responseText);
// 将解析后端数据并保存在对象res
var res=JSON.parse(xhr.responseText);
console.log(res);
// 从后端获取status值
switch(res.status){
case 0:
error = res.message;
break;
case 1:
error = res.message;
break;
default:
error = "未知错误";
}
var span = document.createElement('span');
span.innerHTML=error;
span.style.color="red";
form.appendChild(span);
};
};
// 3. 初始化请求参数: `open(请求类型,请求地址,是否异步)`
xhr.open("POST","test4.php",true);
// 传入表单数据
var data =new FormData(form);
// 在数据中加入时间戳
data.append("login_time",new Date().getTime());
// 4. 发送请求: `send()`
xhr.send(data);
};
// 清除提示信息
var input =document.querySelectorAll('input');
for (var i = 0 ;i <input.length;i++){
input[i].oninput =function(){
if(btn.nextElementSibling !== null)
form.removeChild(btn.nextElementSibling);
};
}
</script>
</body>
</html>
<?php
// print_r($_POST);
// 链接数据库
$pdo = new PDO('mysql:host=localhost;dbname=phpedu', 'root', 'root');
$stmt = $pdo->prepare("SELECT COUNT(`id`) FROM `users` WHERE `email`=? AND `password`=? LIMIT 1");
$stmt->execute([$_POST['email'], $_POST['password']]);
$user = $stmt->fetch(PDO::FETCH_NUM);
// print_r($user);
// 判断数据,并向前端发送
if($user[0] == 1 ) echo json_encode(['status'=>1,'message'=>'验证通过']);
else echo json_encode(['status'=>0,'message'=>'验证不通过']);
总结
- Ajax请求的步骤:1、创建请求对象,2、监听请求回调,3、初始化请求参数,4、发送请求。
- 使用
JSON.parse()
解析JSON字符串