主要内容:
- json文件的反译,转为js对象(是延续上节的内容)-demo1、demo2
- Ajax获取数据之GET方法
- Ajex获取方法之POST方法(三种),其中的FormData最简洁
- 实战:一个登陆验证
- json在js和php中的操作(stringify vs parse, encode vs decode)
类型 | 包装发出 | 接收解析 |
---|---|---|
js | JSON.stringify() | JSON.parse() |
将json对象转换成json字符串 | 将json字符串对象化 | |
php | json_encode() | json_decode() |
对象json化 | json对象普通化 |
- 于是在php和js之间传递数据的时候,会出现stringify(js中)对decode(php中);也会出现encode(php中)对parse(js)中。
1. Ajax的基本知识
- 解决异步问题
1-1. 同步与异步
- 同步: 前端发出一个请求, 必须等后端响应完成,才允许发送另一个请求
- 异步: 前端发出一个请求之后不等后端响应完成继续执行, 后端响应完成之后通过一个事件来通知前端进行处理
1-2. XMLHttpRequest 对象
- XMLHttpRequest 是浏览器提供的 API, 处理异步请求,并非 JS 内置对象
- 基本流程:
- 创建请求对象:
new XMLHttpRequest()
- 监听请求回调:
onreadystatechange
- 初始化请求参数:
open(请求类型,请求地址,是否异步)
- 发送请求:
send()
- 如果是
POST
请求,以上步骤略有不同
- 创建请求对象:
new XMLHttpRequest()
- 监听请求回调:
onreadystatechange()
- 初始化请求参数:
open(请求类型,请求地址,是否异步)
- 设置请求头:
setRequestHeader()
- 准备请求参数: 可选
var data = ...
- 发送请求:
send(data)
2. json字符串转js对象
- demo1.html:parse先反译,然后再渲染过去
- 这个是简单的方法,直接传进前端。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>json字符串转js对象</title>
</head>
<body>
<ul>
<li></li>
<li></li>
<li></li>
</ul>
<script>
var str =
'{\
"name": "朱老师",\
"sex": "男",\
"age": 88\
}';
// 将json字符串的数据渲染到页面中
// 先将json字符串转为js对象
var obj = JSON.parse(str);
console.log(obj);
console.log(obj.name);
var li1 = document.querySelector("li:first-of-type");
li1.innerHTML = obj.name;
var li2 = document.querySelector("li:nth-of-type(2)");
li2.innerHTML = obj.sex;
var li3 = document.querySelector("li:last-of-type");
li3.innerHTML = obj.age;
</script>
</body>
</html>
- demo2.html:有条件地反译,并通过js向body中加入内容
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>json转js对象2</title>
</head>
<body>
<script>
var jsonStr =
'{"name":"Peter Zhu",\
"age":29,\
"isMarried":true,\
"course":{"name":"JavaScript","grade":99}}';
// 这个地方的\是转意符,否则分行会显示错误,只能在一行。
var obj = JSON.parse(jsonStr, function (key, value) {
if (key === "isMarried") {
return "本人已婚,有事烧纸";
}
//必须加下以下语句,否则无输出
return value;
});
// 控制台打印结果
// console.log(obj);
// 下面为经过转化和拼接,最终在显示器中显示出来。
var person = {
name: obj.name,
age: obj.age,
courseName: obj.course.name,
courseGrade: obj.course.grade,
};
// console.log(person);
var ul = document.createElement("ul");
var res = "";
for (var key in person) {
// console.log(person[key]);
res += "<li>" + person[key] + "</li>";
}
console.log(res);
ul.innerHTML = res;
document.body.appendChild(ul);
</script>
</body>
</html>
3. Ajax获取数据-GET
- 一个html文件,中间放js
- 一个php文件,被js来调用
- php中通过echo json_encode()来传数据,js中通过JSON.parse(xhr.responseText)来接收。
(demo3.html)
<!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>
<button>获取数据</button>
<p></p>
<p></p>
<script>
var btn = document.querySelector("button");
btn.addEventListener("click", getData, false);
function getData() {
// 1. 创建ajax对象
var xhr = new XMLHttpRequest();
// 2. 监听请求
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
// readyState只有四种状态,4的时候代表成功。
// status以2开头的代表成功,3开头代表重名项,4开头的代表错误,例如403;5开头的代表服务器故障。
// 请求成功的返回的文本数据保存在responseText属性中
console.log(xhr.responseText);
// 将数据渲染到页面中
// 凡涉及页面的DOM操作全部放到监听请求的回调中处理
var obj = JSON.parse(xhr.responseText);
// console.log(obj);
// document.querySelector("p:first-of-type").innerHTML = obj.name;
// document.querySelector("p:last-of-type").innerHTML = obj.email;
}
};
// 3. 初始化请求参数
// xhr.open(请求类型, 请求的地址URL, 是否异步)
// xhr.open("get", "test1.php", true);
xhr.open("GET", "test1.php?id=2");
// 4. 发送请求
xhr.send(null);
}
</script>
</body>
</html>
(对应的test1.php)
<?php
// $user = [
// 'name' => 'peter zhu',
// 'email'=> 'peter@php.cn'
// ];
$users = [
[
'id'=>1,
'name' => 'peter zhu',
'email'=> 'peter@php.cn'
],
[
'id'=>2,
'name' => 'Jake ma',
'email'=> 'jake@php.cn'
]
];
$id = $_GET['id'];
echo $id;
// 将数组转为json格式的字符串,返回前端
// return $user;
// return json_encode($user);
// 必须要用echo 才可写入输出流
// echo json_encode($users);
4. Ajax获取数据-POST1
- 用post方式将数据从前端传递到服务器上
- 模拟表单键值对方式,将json转为字符串然后传过去
- js中通过JSON.stringify()来字符串化,php中通过json_decode()来转化(当然前面需要先将json通过key取出来)
(demo4.html)
<!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>
<button>获取数据</button>
<script>
var btn = document.querySelector("button");
btn.addEventListener("click", getData, false);
function getData() {
// 1. 创建ajax对象
var xhr = new XMLHttpRequest();
// 2. 监听请求
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
// 请求成功的返回的文本数据保存在responseText属性中
console.log(xhr.responseText);
// 将数据渲染到页面中
// 凡涉及页面的DOM操作全部放到监听请求的回调中处理
// var obj = JSON.parse(xhr.responseText);
// console.log(obj);
}
};
// 3. 初始化请求参数
xhr.open("POST", "test2.php");
// 4. 设置请求头: `setRequestHeader()`
// 模拟表单键值对方式进行发送
xhr.setRequestHeader(
"content-type",
"application/x-www-form-urlencoded"
);
// 准备一下数据(模拟表单键值对)
var user = {
email: "admin@php.cn",//这块也可以来自表单,例如form.email
password: "123456",
};
// 再把js对象转为json字符串
var data = JSON.stringify(user);
// 5. 发送请求, 发送到服务器上的是json格式字符串
// xhr.send(data);
xhr.send(data);
}
</script>
</body>
</html>
(test2.php)
<?php
// print_r($_POST);
// 直接用$_POST,前端的json字符串成了唯一元素的键名了
// Array
// (
// [{"email":"admin@php_cn","password":"123456"}] =>
// )
// 对json传过来的array进行转化,等于将json字符串取出然后生成data。
// 因为之前就是在一个数组中以key的方式存在,因此通过key方式取出。
$data = key($_POST);
// echo $data;
// 下一步, 就是将前端提交过来的json解析成当前编程语言能识别的数据类型
// 比如,对象, 数组
// json_decode()默认将json解析为对象
$user = json_decode($data);
// echo gettype($user);
echo $user->email, ': ', sha1($user->password);
// 也可以将json解析成php数组,当然你这种方式提取元素的方式也就发生改变。
// $user = json_decode($data,true);
// echo $user['email'], ': ', sha1($user['password']);
5. Ajax获取数据-POST2
- js中通过JSON.stringify()直接传json,服务器端再通过file_get_contents得到,再通过json_decode()来转化
(demo5.html)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Ajax-POST-2</title>
<!--这种适合写接口-->
</head>
<body>
<button>获取数据</button>
<script>
var btn = document.querySelector("button");
btn.addEventListener("click", getData, false);
function getData() {
// 1. 创建ajax对象
var xhr = new XMLHttpRequest();
// 2. 监听请求
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
// 请求成功的返回的文本数据保存在responseText属性中
console.log(xhr.responseText);
}
};
// 3. 初始化请求参数
xhr.open("POST", "test3.php");
// 4. 设置请求头: `setRequestHeader()`
// 直接将内容类型设置为json - 这个地方是区别于demo4的地方。
xhr.setRequestHeader("content-type", "application/json;charset=utf-8");
// json默认也是utf-8,因此charset等内容可以省略掉。
// 后端的php使用标准输入流来获取 php://input
// 准备一下数据(模拟表单键值对)
var user = {
email: "admin@php.cn",
password: "123456",
};
// 再把js对象转为json字符串
var data = JSON.stringify(user);
// 5. 发送请求, 发送到服务器上的是json格式字符串
xhr.send(data);
}
</script>
</body>
</html>
(test3.php)
<?php
// print_r($_POST);
// 从当前的输入流中获取数据。因为$_POST只能从表单中获取数据,或者以表单的形式获取数据。
$data = file_get_contents('php://input');
// echo $data;
// php对象
$user = json_decode($data);
print_r($user);
6. Ajax获取数据-POST3
- 用Formdata来post数据到服务器端
(demo6.html)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Ajax-POST-3-FormData</title>
</head>
<body>
<button>获取数据</button>
<script>
var btn = document.querySelector("button");
btn.addEventListener("click", getData, false);
function getData() {
// 1. 创建ajax对象
var xhr = new XMLHttpRequest();
// 2. 监听请求
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
console.log(xhr.responseText);
}
};
// 3. 初始化请求参数
xhr.open("POST", "test4.php");
// 4. 使用FormData来组织数据,最终仍是以表单数据方式发送
var data = new FormData();
data.append("username", "admin");
data.append("passowrd", "admin888");
// 5. 发送请求, 发送到服务器上的是json格式字符串
xhr.send(data);
}
</script>
</body>
</html>
(test4.php)
<?php
// print_r($_POST);
// 从当前的输入流中获取数据。因为$_POST只能从表单中获取数据,或者以表单的形式获取数据。
$data = file_get_contents('php://input');
// echo $data;
// php对象
$user = json_decode($data);
print_r($user);
7. 实战-一个表单的验证
-
(demo7.html)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>ajax-json-formdata</title>
</head>
<body>
<p>请登录:</p>
<form
action=""
method="POST"
style="display: grid; gap: 15px;"
onsubmit="return false"
>
<input
type="email"
name="email"
placeholder="exam@email.com"
required
autofocus
/>
<input type="password" name="password" placeholder="******" required />
<button>提交</button>
</form>
<script>
// 1. 获取表单和按钮
var form = document.querySelector("form");
var btn = document.querySelector("form button");
// 2. 给按钮绑定事件
btn.onclick = function () {
// 1. 创建ajax对象
var xhr = new XMLHttpRequest();
// 2. 监听请求
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
// console.log(xhr.responseText);
var res = JSON.parse(xhr.responseText);
console.log(res);
// 根据后端返回的状态进行判断
switch (res.status) {
case 0:
case 1:
error = res.message;
break;
default:
error = "未知错误";
}
// 将error信息渲染到页面中
var span = document.createElement("span");
span.innerHTML = error;
form.appendChild(span);
}
};
// 3. 初始化请求参数
xhr.open("POST", "test5.php");
// 4. 使用FormData来组织数据,最终仍是以表单数据方式发送
var data = new FormData(form); //用这种方式取代每个变量的绑定
// data.append("email", form.email.value);
// data.append("passowrd", form.password.value);
// 5. 发送请求, 发送到服务器上的是json格式字符串
xhr.send(data);
};
</script>
</body>
</html>
(test5.php)
<?php
// print_r($_POST);
$users = [
['id'=>1,'email'=>'peter@php.cn', 'password'=>'123'],
['id'=>2,'email'=>'peter@qq.com', 'password'=>'888'],
];
// 上面的数据也可以是从数据库中查询出来然后进行匹对,这个地方直接给更多是为了演示。
$status = 0; $message = '<span style="color:red">邮箱或密码错误</span>';
// $status = 0; $message = '邮箱或密码错误';
foreach ($users as $user) {
if ($user['email'] == $_POST['email'] && $user['password'] == $_POST['password']) {
$status = 1;
$message = '<span style="color:green">验证通过</span>';
// $message = '验证通过';
}
}
echo json_encode(['status'=>$status, 'message'=> $message]);
8. 作业
0812-作业
- 将今晚的ajax,json,formdata的相关案例, 在本地至少要写三遍以上(不用提交博客)
- 完善最后一个案例, 使用数据表进行用户信息验证,并提交到博客中
- 下面为php部分,js部分没有太大变化
<?php
// 数据库连接及数据获取部分
$pdo = new PDO('mysql:host=localhost;dbname=liangtest', 'liang', '123456');
$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
$sql_login = "SELECT `email`, `password` FROM `pro_0member`";
$logins = $pdo->query($sql_login)->fetchAll();
// print_r($logins);
//在实际运营中上面这行不能有,否则会出现错误。奇葩!
$status = 0; $message = '<span style="color:red">邮箱或密码错误</span>';
foreach ($logins as $user) {
if ($user['email'] == $_POST['email'] && $user['password'] == $_POST['password']) {
$status = 1;
$message = '<span style="color:green">验证通过</span>';
// $message = '验证通过';
}
}
echo json_encode(['status'=>$status, 'message'=> $message]);
$pdo = null;
// 最下面这个太关键了,已经要加上,已经要加上,否则出错。