Blogger Information
Blog 47
fans 1
comment 0
visits 52936
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
JS - Ajax基础与实战
晴天
Original
601 people have browsed it

Ajax

1.同步与异步

以前端请求,后端响应为例

  • 同步:前端请求发送,必须等到后端响应完成,才允许发送另一个请求
  • 异步:前端发请求后不等待后端响应结果继续执行,后端响应完成通过事件通知前端处理

异步最常用的处理形式就是回调函数

2. XMLHttpRequest 对象

  • XMLHttpRequest是浏览器提供的,处理异步请求的宿主对象,而非 Js 内置对象
  • 基本流程:
    • 1.创建请求对象:new XMLHttpRequest()
    • 2.监听请求回调:onreadystatechange
    • 3.初始化请求参数:open(请求类型,请求地址,是否异步)
    • 4.发送请求:send()
  1. // 1. 创建ajax对象
  2. var xhr = new XMLHttpRequest();
  3. // 2.监听请求
  4. xhr.onreadystatechange = function () {
  5. if (xhr.readyState === 4 && xhr.status === 200) {
  6. // 控制台输出返回的数据
  7. console.log(xhr.responseText); //输出 {"name":"peter","age":23}
  8. }
  9. };
  10. // 3.初始化请求参数
  11. xhr.open("GET", "test1.php?action=demo1", true);
  12. // 4.发送请求
  13. xhr.send(null);

php 部分

  1. case 'demo1':
  2. // 创建数组
  3. $user['name'] = 'peter';
  4. $user['age'] = 23;
  5. // JSON 编码返回
  6. echo json_encode($user);
  7. break;
  • 如果是 post 请求,步骤略有不同
    • 1.创建请求对象 new XMLHttpRequest()
    • 2.监听请求回调 onreadystatechange
    • 3.初始化请求参数 open(请求类型,请求地址,是否异步)
    • 4.设置请求头 setRequestHeader()
    • 5.准备请求参数(可选) var data = ...
    • 6.发送请求 send(data)
  1. // 创建对象
  2. var xhr = new XMLHttpRequest();
  3. // 监听请求
  4. xhr.onreadystatechange = function () {
  5. if (xhr.readyState === 4 && xhr.status === 200) {
  6. console.log(xhr.responseText);
  7. // 返回值 Array
  8. // (
  9. // [name] => peter
  10. // [age] => 56
  11. // )
  12. }
  13. };
  14. // 初始化请求参数
  15. xhr.open("POST", "test1.php?action=demo2", true);
  16. // 设置请求头
  17. xhr.setRequestHeader("content-type", "application/x-www-form-urlencoded");
  18. // 创建对象
  19. var user = {
  20. name: "peter",
  21. age: "56",
  22. };
  23. // 转JSON
  24. var data = JSON.stringify(user);
  25. // 发送请求
  26. xhr.send(data);

php 部分

  • 方法 1
  1. case 'demo2':
  2. print_r($_POST);
  3. // 这里输出的是 Array
  4. // (
  5. // [{"name":"peter","age":"56"}] =>
  6. // )
  7. // 所以要获取一下键
  8. $data = key($_POST);
  9. $user = json_decode($data,true);
  10. print_r($user);
  11. break;
  • 方法 2
  1. case 'demo3':
  2. $data = file_get_contents('php://input');
  3. $user = json_decode($data,true);
  4. print_r($user);
  5. break;

3. GET 请求

  • 服务器:返回JSON
  • 前端: JSON.parse()解析 JSON 字符串

4. POST 请求

  • 前端:发送JSON
  • 后端:
    • JSON 数据以表单数据类型发送,可$_POST接收
    • JSON 数组就是以 JSON 发送,php://input 流文件方式接收

5. FormData

  • 可直接序列化表单数据
  • 可直接被 Ajax 识别,所以可以不设置请求头
  • 除了表单数据外,也可用于普通数据
  1. // 创建 ajax对象
  2. var xhr = new XMLHttpRequest();
  3. // 监听数据返回
  4. xhr.onreadystatechange = function () {
  5. if (xhr.readyState === 4 && xhr.status === 200) {
  6. console.log(xhr.responseText);
  7. // 返回 Array
  8. // (
  9. // [username] => admin
  10. // [password] => admin888
  11. // )
  12. }
  13. };
  14. // 初始化请求参数
  15. xhr.open("POST", "test1.php?action=demo4");
  16. // FormData 传值
  17. var data = new FormData();
  18. data.append("username", "admin");
  19. data.append("password", "admin888");
  20. // 发送请求
  21. xhr.send(data);

php 部分

  1. case 'demo4':
  2. // 可以直接获取到值
  3. print_r($_POST);
  4. break;

6. 实战

  • 实战内容 :

    • 异步请求完成点击刷新验证码
    • 异步请求完成登录并在验证通过后自动跳转到首页
  • 演示地址: http://php.rc238.cn/0522

index.php

  1. <?php
  2. session_start();
  3. //先判断有没有sesssion 没有跳去登录
  4. if (!isset($_SESSION['user'])){
  5. die("<script>location.href='login.html';</script>");
  6. }
  7. //向下执行
  8. $session = unserialize($_SESSION['user']);
  9. //直接输出数据
  10. var_dump($session);
  11. echo "<a href='handle.php?action=logout'>点这里退出登录</a>";

login.html

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8" />
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  6. <link rel="stylesheet" href="css/style.css" />
  7. <title>登录</title>
  8. </head>
  9. <body>
  10. <form action="" onsubmit="return false">
  11. <h2>用户登录</h2>
  12. <input
  13. type="email"
  14. name="email"
  15. placeholder="email@php.cn"
  16. required
  17. autofocus
  18. />
  19. <input
  20. type="password"
  21. name="password"
  22. placeholder="password for php.cn"
  23. required
  24. />
  25. <div>
  26. <input type="text" name="captch" required placeholder="验证码" />
  27. <button type="button">点击获取验证码</button>
  28. <img src="" alt="" />
  29. </div>
  30. <button>登录</button>
  31. </form>
  32. </body>
  33. <script>
  34. ////////////////////////////////////////
  35. // 获取验证码按钮 和 img
  36. var captch_btn = document.querySelector("form > div > button");
  37. var img = document.querySelector("form > div > img");
  38. // 验证码按钮被单击
  39. captch_btn.onclick = function () {
  40. // 隐藏按钮
  41. captch_btn.style.display = "none";
  42. // 显示img
  43. img.style.display = "inline";
  44. // 创建异步请求 请求验证码
  45. var xhr = new XMLHttpRequest();
  46. // 监听请求
  47. xhr.onreadystatechange = function () {
  48. if (xhr.readyState === 4 && xhr.status === 200) {
  49. img.src = xhr.responseText;
  50. }
  51. };
  52. // 初始化请求参数
  53. xhr.open("get", "handle.php?action=captch", true);
  54. // 发送请求
  55. xhr.send(null);
  56. };
  57. // 图片被单击
  58. img.onclick = function () {
  59. // 创建异步请求 请求验证码
  60. var xhr = new XMLHttpRequest();
  61. // 监听请求
  62. xhr.onreadystatechange = function () {
  63. if (xhr.readyState === 4 && xhr.status === 200) {
  64. // 修改src属性
  65. img.src = xhr.responseText;
  66. }
  67. };
  68. // 初始化请求参数
  69. xhr.open("get", "handle.php?action=captch", true);
  70. // 发送请求
  71. xhr.send(null);
  72. };
  73. ///////////////////////////////////////
  74. // 登录按钮被单击
  75. // 获取表单 和按钮
  76. var form = document.querySelector("form");
  77. var btn = document.querySelector("form > button");
  78. // 点击事件
  79. btn.onclick = function () {
  80. // 创建ajax对象
  81. var xhr = new XMLHttpRequest();
  82. // 监听返回数据
  83. xhr.onreadystatechange = function () {
  84. if (xhr.readyState === 4 && xhr.status === 200) {
  85. // 反序列化JSON
  86. var msg = JSON.parse(xhr.responseText);
  87. if (msg.message === 1) {
  88. // 跳转去首页
  89. location.href = msg.href;
  90. } else {
  91. // 创建span标签
  92. var span = document.createElement("span");
  93. // 给个值
  94. span.innerHTML = msg.error;
  95. // 换个颜色
  96. span.style.color = "red";
  97. // 标签插入到form表单中
  98. form.appendChild(span);
  99. }
  100. }
  101. };
  102. // 初始化请求参数
  103. xhr.open("POST", "handle.php?action=login", true);
  104. // 获取到表单数据
  105. var data = new FormData(form);
  106. // 发送请求
  107. xhr.send(data);
  108. };
  109. // 清除一下提示信息
  110. var inputs = document.querySelectorAll("input");
  111. for (var i = 0; i < inputs.length; i++) {
  112. // 当有一个input被选中时
  113. inputs[i].oninput = function () {
  114. // 如果button的后面存在元素
  115. if (btn.nextElementSibling !== null) {
  116. // 先获取到span;
  117. var spans = document.querySelectorAll("span");
  118. for (var i = 0; i < spans.length; i++) {
  119. // 循环删除
  120. form.removeChild(btn.nextElementSibling);
  121. }
  122. }
  123. };
  124. }
  125. </script>
  126. </html>

handle.php

  1. <?php
  2. //先判断请求是否合法
  3. if (!isset($_GET['action'])){
  4. die('非法请求');
  5. }
  6. require 'vendor/autoload.php';
  7. use Gregwar\Captcha\CaptchaBuilder;
  8. //开启session
  9. session_start();
  10. //获取action指令
  11. $action = $_GET['action'];
  12. //执行
  13. switch ($action){
  14. // 验证码
  15. case "captch":
  16. $builder = new CaptchaBuilder(4);
  17. $builder->build();
  18. $_SESSION['phrase'] = $builder->getPhrase();
  19. echo $builder->inline();
  20. break;
  21. // 登录
  22. case 'login':
  23. // 先判断验证码是否正确
  24. if (!stristr($_SESSION['phrase'],$_POST['captch'],false)){
  25. die(json_encode(['message'=>0 , 'error'=> '验证码错误']));
  26. }
  27. // 查找数据库
  28. $pdo = new PDo('mysql:host=localhost;dbname=php11.edu','php11.edu','php11.edu');
  29. $stmt = $pdo->prepare('SELECT * FROM `admin` WHERE `email`=? AND `password` = ?');
  30. $stmt->execute([$_POST['email'],sha1($_POST['password'])]);
  31. $user = $stmt->fetch(PDO::FETCH_ASSOC);
  32. // 判断有没有返回数据
  33. if ($user !== false){
  34. // 有数据创建session
  35. $_SESSION['user'] = serialize($user);
  36. // 序列化返回
  37. echo json_encode(['message'=>1 , 'href'=>'index.php']);
  38. }else{
  39. // 没有数据说明密码或邮箱错误
  40. echo json_encode(['message'=>2 , 'error'=> '邮箱或密码错误']);
  41. }
  42. break;
  43. // 退出
  44. case 'logout':
  45. if (session_destroy()) {
  46. echo '<script>alert("退出成功");location.href="index.php";</script>';
  47. }
  48. break;
  49. }

style.css

  1. * {
  2. margin: 0px;
  3. padding: 0px;
  4. box-sizing: border-box;
  5. }
  6. body {
  7. min-height: 100vh;
  8. min-width: 100vw;
  9. background-color: lightskyblue;
  10. display: flex;
  11. justify-content: center;
  12. align-items: center;
  13. }
  14. form {
  15. width: 400px;
  16. gap: 20px;
  17. display: grid;
  18. padding: 20px;
  19. background-color: #fff;
  20. border: none;
  21. border-radius: 10px;
  22. box-shadow: 1px 1px 5px black;
  23. }
  24. form input {
  25. height: 30px;
  26. border: none;
  27. border: 1px solid #ccc;
  28. border-radius: 3px;
  29. text-indent: 20px;
  30. }
  31. form div {
  32. height: 30px;
  33. display: flex;
  34. justify-content: space-between;
  35. }
  36. form > div > input {
  37. width: 200px;
  38. }
  39. form > div > button {
  40. margin-right: 20px;
  41. width: 120px;
  42. border: none;
  43. padding: 5px;
  44. border-radius: 3px;
  45. background-color: #cfcfcf;
  46. color: red;
  47. }
  48. form > div > button:hover {
  49. background-color: grey;
  50. color: #fff;
  51. }
  52. form > div > img {
  53. margin-right: 20px;
  54. width: 120px;
  55. border-radius: 3px;
  56. display: none;
  57. }
  58. form > button {
  59. height: 30px;
  60. border: none;
  61. background-color: lightseagreen;
  62. color: #fff;
  63. font-size: 1.2rem;
  64. letter-spacing: 20px;
  65. border-radius: 10px;
  66. }
  67. form > button:hover {
  68. background-color: limegreen;
  69. }

关于验证码

  1. composer require gregwar/captcha

7. 总结

本来打算把注册也写上的,写得太慢了,写着写着就六点了,只能用已有的账号密码演示了,删除 span 提示标签时,按教案写法结果为 input 删除一个字,span 删除一条 在里面又加了一个循环完美解决 实现删除一个字,span 全部删除

Correcting teacher:天蓬老师天蓬老师

Correction status:qualified

Teacher's comments:事件有空多看看
Statement of this Website
The copyright of this blog article belongs to the blogger. Please specify the address when reprinting! If there is any infringement or violation of the law, please contact admin@php.cn Report processing!
All comments Speak rationally on civilized internet, please comply with News Comment Service Agreement
0 comments
Author's latest blog post