博客列表 >js基础知识:Ajax的get,post异步请求 及 选项卡、换肤实例

js基础知识:Ajax的get,post异步请求 及 选项卡、换肤实例

未来星
未来星原创
2021年04月24日 22:58:031162浏览

一、 JSON 是什么

  • JSON: JavaScript Object Notation(JS 对象表示法)
  • JSON 独立于任何编程语言, 几乎所有编程语言都提供了访问 JSON 数据的 API 接口
  • JSON 是一种语法,用来序列化其它语言创建的数据类型
  • JSON 仅支持 6 种数据类型:对象,数组,数值,字符串,布尔值,null
  • JSON 只是借用了 JS 中的一些数据表示语法,与 JS 并无关系

1、JSON 数据类型

序号 类型 描述
1 简单值 数值,字符串,布尔,null
1 复合值 对象,数组

注意: 不支持undefined(因为除 JS 外,其它语言中没有这个东西)

2、JS 解析 JSON 的 API

序号 方法 描述
1 JSON.stringify() 将 JS 对象,序列化为 JSON 字符串
2 JSON.parse() 将 JSON 字符串,解析为 JS 对象

二、Ajax异步请求

Ajax即Asynchronous Javascript And XML(异步JavaScript和XML),Ajax是一种用于创建快速动态网页的技术。通过在后台与服务器进行少量数据交换,Ajax可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。而传统的网页(不使用 Ajax)如果需要更新内容,必需重载整个网页面。

1、工作原理

  • 同步与异步的区别
    同步提交:当用户发送请求时,当前页面不可以使用,服务器响应页面到客户端,响应完成,用户才可以使用页面。
    异步提交:当用户发送请求时,当前页面还可以继续使用,当异步请求的数据响应给页面,页面把数据显示出来 。
  • ajax的工作原理
    客户端发送请求,请求交给xhr,xhr把请求提交给服务,服务器进行业务处理,服务器响应数据交给xhr对象,xhr对象接收数据,由javascript把数据写到页面上。

2、XMLHttpRequest 对象
XMLHttpRequest 对象用于在后台与服务器交换数据。XMLHttpRequest是浏览器对象,而非 JS 内置对象,所有现代的浏览器都支持 XMLHttpRequest 对象。

  • xhr 请求步骤
    创建 xhr 对象: const xhr = new XMLHttpRequest()
    配置 xhr 参数: xhr.open(type, url)
    处理 xhr 响应: xhr.onload = (...) => {...}
    发送 xhr 请求: xhr.send(...)

  • xhr 对象常用属性

序号 方法 描述
1 responseType 设置响应类型
2 response 响应正文
  • xhr 对象常用方法
序号 方法 描述
1 open(type,url) 配置请求参数
2 send(data/null) 发送请求
  • xhr 对象常用事件
序号 事件 描述
1 load() 请求成功
2 error() 请求失败

3、FormData 对象
FormData是表单数据构造器

序号 方法 描述
1 append(name,value) 添加新的键值对
2 delete(name) 删除键值对

4、get / post 区别

  • get 是 url 传参,post 是request body请求体传参
  • get 回退无影响, post 回退会重复提交
  • get 生成的 url 可做书签,post 不可以
  • get 只能对 url 进行编码, post 支持多种编码
  • get 请求参数会保留在历史记录中, post 参数不保留
  • get 参数长度受限,post 无限制
  • get 只接受 ascii 码字符,post 无限制
  • get,post 底层实现是一致的,都是基于 http 协议
  • get 也可以带上 request body, post 也可以带上 url 参数
  • get 产生一个 tcp 数据包,post 产生二个 tcp 数据包
  • get 产生一个请求, post 产生二个请求
  • get 请求,浏览器将 header,data 一起发出,服务器响应 200 成功
  • post 请求,浏览器先发出 header,得到响应 100 continue,再发出 data,得到响应 200
  • 并非所有浏览器的 post 都产生二次 http 请求,firefox 就只产生一次

5、跨域

  • CORS: 跨域资源共享
  • 跨域请求可以是 get,也可以是 post,只不过 get 居多
  • cors-post 时,需要在服务器端进行头部设置
  • jsonp 只能是 get

》 Ajax-get请求实例:

html文件代码块:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8" />
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  7. <title>Ajax-Get方式</title>
  8. </head>
  9. <body>
  10. <button>Ajax-GET请求测试</button>
  11. <p></p>
  12. <script>
  13. // 获取元素
  14. const btn = document.querySelector("button");
  15. // 按钮提交事件
  16. btn.onclick = () => {
  17. // 1. 创建 xhr 对象:
  18. const xhr = new XMLHttpRequest();
  19. // 2. 配置 xhr 参数:
  20. xhr.open("get", "test1.php?id=1");
  21. xhr.responseType = "json";
  22. // 3. 处理 xhr 响应:
  23. xhr.onload = () => {
  24. // xhr.response返回处理结果
  25. let user = `用户:${xhr.response.name} <br> 邮箱:${xhr.response.email} <br> 密码:${xhr.response.password}`;
  26. // 显示到页面元素位置
  27. document.querySelector("p").innerHTML = user;
  28. };
  29. xhr.onerror = () => console.log("Error");
  30. // 4. 发送 xhr 请求: `xhr.send(...)`
  31. xhr.send(null);
  32. };
  33. </script>
  34. </body>
  35. </html>

php文件代码块:

  1. <?php
  2. // 以二维数组模拟数据表信息
  3. $users = [
  4. ['id'=>1, 'name'=>'天蓬','email'=>'tp@php.cn','password' => md5('123456')],
  5. ['id'=>2, 'name'=>'灭绝','email'=>'mj@php.cn','password' => md5('abc123')],
  6. ['id'=>3, 'name'=>'西门','email'=>'xm@php.cn','password' => md5('abc888')],
  7. ];
  8. // 查询条件
  9. $id = $_GET['id'];
  10. // 在id组成的数组中查询是否存在指定的id,并返回对应的键名
  11. $key = array_search($id,array_column($users,'id'));
  12. // 根据键名返回指定的用户信息
  13. echo json_encode($users[$key]);

》 Ajax-post请求实例:

html文件代码块:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8" />
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  7. <title>Ajax-POST方式</title>
  8. <style>
  9. body {
  10. background-color: lightcyan;
  11. }
  12. .login {
  13. width: 20em;
  14. /*border: 1px solid;*/
  15. border-radius: 10px;
  16. box-shadow: 0 0 8px #888;
  17. padding: 0 1em 1em;
  18. background-color: lightseagreen;
  19. color: white;
  20. margin: 2em auto;
  21. display: grid;
  22. place-items: center;
  23. }
  24. .login form {
  25. display: grid;
  26. grid-template-columns: 3em 1fr;
  27. gap: 1em 0;
  28. }
  29. .login form input {
  30. border: none;
  31. outline: none;
  32. }
  33. .login form input:focus,
  34. .login form input:hover {
  35. box-shadow: 0 0 5px lime;
  36. }
  37. .login form button {
  38. background-color: lightsalmon;
  39. color: white;
  40. outline: none;
  41. border: none;
  42. height: 2em;
  43. }
  44. .login form button:hover {
  45. background-color: salmon;
  46. cursor: pointer;
  47. box-shadow: 0 0 5px lime;
  48. }
  49. /* 按钮与提示信息显示在第二列 */
  50. .login form button,
  51. .tips {
  52. grid-area: auto / 2;
  53. }
  54. </style>
  55. </head>
  56. <body>
  57. <div class="login">
  58. <p>用户登录</p>
  59. <form action="" onsubmit="return false">
  60. <label for="email">邮箱:</label>
  61. <input type="email" name="email" id="email" placeholder="demo@email.com" />
  62. <label for="password">密码:</label>
  63. <input type="password" name="password" id="password" placeholder="不少于6位" />
  64. <button>提交</button>
  65. <span class="tips"></span>
  66. </form>
  67. </div>
  68. <script>
  69. const form = document.querySelector(".login form");
  70. const btn = document.querySelector(".login button");
  71. const tips = document.querySelector(".tips");
  72. btn.onclick = (ev) => {
  73. // FormData: 表单数据的序列化
  74. let data = new FormData(form);
  75. // console.log(data.get("email"), data.get("password"));
  76. // 默认的提交行为
  77. ev.preventDefault();
  78. // 1. 创建 xhr 对象:
  79. const xhr = new XMLHttpRequest();
  80. // 2. 配置 xhr 参数:
  81. xhr.open("post", "test2.php");
  82. // xhr.responseType = "text";
  83. // 3. 处理 xhr 响应:
  84. xhr.onload = () => {
  85. tips.textContent = xhr.response;
  86. };
  87. xhr.onerror = () => console.log("Error");
  88. // 4. 发送 xhr 请求:
  89. xhr.send(new FormData(form));
  90. };
  91. </script>
  92. </body>
  93. </html>

php文件代码块:

  1. <?php
  2. // 使用二维数组模拟用户数据表信息
  3. $users = [
  4. ['id' => 1, 'name' => '天蓬', 'email' => 'tp@php.cn', 'password' => md5('123456')],
  5. ['id' => 2, 'name' => '灭绝', 'email' => 'mj@php.cn', 'password' => md5('abc123')],
  6. ['id' => 3, 'name' => '西门', 'email' => 'xm@php.cn', 'password' => md5('abc888')],
  7. ];
  8. // 将通过post获取的数据保存到临时变量中
  9. $email = $_POST['email'];
  10. $password = md5($_POST['password']);
  11. // 使用数组过滤器查询是否存在指定的用户并返回结果
  12. $res = array_filter($users, function ($user) use ($email, $password) {
  13. return $user['email'] === $email && $user['password'] === $password;
  14. });
  15. // 将结果做为请求响应返回到前端
  16. echo count($res) === 1 ? '验证成功' : '验证失败';

三、一键换肤实例


利用事件代理,实现更换背景图片。html文件代码块:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8" />
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  7. <title>一键换肤实例</title>
  8. <style>
  9. .container {
  10. width: 300px;
  11. display: grid;
  12. grid-template-columns: repeat(3, 1fr);
  13. column-gap: 10px;
  14. }
  15. .container > img {
  16. width: 100%;
  17. border: 3px solid #fff;
  18. opacity: 0.6;
  19. }
  20. .container > img:active {
  21. opacity: 1;
  22. }
  23. .container > img:hover {
  24. opacity: 1;
  25. cursor: pointer;
  26. width: 110%;
  27. }
  28. body {
  29. background-image: url("./images/1.jpg");
  30. background-size: cover;
  31. background-repeat: no-repeat;
  32. }
  33. </style>
  34. </head>
  35. <body>
  36. <div class="container">
  37. <img src="./images/1.jpg" alt="" />
  38. <img src="./images/2.jpg" alt="" />
  39. <img src="./images/3.jpg" alt="" />
  40. </div>
  41. <script>
  42. // 事件代理
  43. const box = document.querySelector(".container");
  44. box.onclick = function (ev) {
  45. // body
  46. const body = document.body;
  47. // 新的背景图片
  48. let imgUrl = `url('${ev.target.src}')`;
  49. body.style.backgroundImage = imgUrl;
  50. };
  51. // 使用箭头函数来简化
  52. // document.querySelector(".container").onclick = (ev) =>
  53. // (document.body.style.backgroundImage = `url('${ev.target.src}')`);
  54. </script>
  55. </body>
  56. </html>

四、选项卡实例

利用事件代理,实现选项卡列表变化。html文件代码块:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8" />
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  7. <title>选项卡实例</title>
  8. <style>
  9. * {
  10. padding: 0;
  11. margin: 0;
  12. box-sizing: border-box;
  13. }
  14. a {
  15. text-decoration: none;
  16. color: #555;
  17. }
  18. a:hover {
  19. text-decoration: underline;
  20. color: red;
  21. }
  22. li {
  23. list-style: none;
  24. line-height: 1.6em;
  25. }
  26. li:hove {
  27. cursor: pointer;
  28. }
  29. .container {
  30. width: 360px;
  31. height: 300px;
  32. margin: 30px;
  33. background-color: #fff;
  34. display: flex;
  35. flex-flow: column;
  36. }
  37. .tab {
  38. display: flex;
  39. height: 36px;
  40. }
  41. .tab li {
  42. flex: auto;
  43. text-align: center;
  44. line-height: 36px;
  45. border-radius: 20px 20px 0 0;
  46. background-color: #fff;
  47. }
  48. .tab li.active {
  49. background-color: wheat;
  50. }
  51. .tab li:hover {
  52. cursor: pointer;
  53. }
  54. .item {
  55. padding: 20px;
  56. display: none;
  57. background-color: wheat;
  58. }
  59. .item.active {
  60. display: block;
  61. }
  62. </style>
  63. </head>
  64. <body>
  65. <div class="container">
  66. <!-- 导航 -->
  67. <ul class="tab">
  68. <li data-index="1" class="active">省内</li>
  69. <li data-index="2">国内</li>
  70. <li data-index="3">国际</li>
  71. </ul>
  72. <!-- 与导航标签对应的列表 -->
  73. <ul data-index="1" class="item active">
  74. <li><a href="">河南特斯拉车主维权最新回应</a></li>
  75. <li><a href="">五一高速免费吗?哪些路段时段堵</a></li>
  76. <li><a href="">特斯拉刹车失灵事件持续 行车数据</a></li>
  77. <li><a href="">共享单车违停费涨到了20元? </a></li>
  78. <li><a href="">重磅!河南两市最新人事任免发布</a></li>
  79. </ul>
  80. <ul data-index="2" class="item">
  81. <li><a href="">南海舰队一次性入列三型主战舰艇</a></li>
  82. <li><a href="">东北虎进村伤人 麻醉针已醒</a></li>
  83. <li><a href="">特斯拉回应广州一车辆撞墙致死事故</a></li>
  84. <li><a href="">9秒98!苏炳添击败谢震业夺冠</a></li>
  85. <li><a href="">中国首辆火星车为何命名“祝融”?寓意深远!</a></li>
  86. </ul>
  87. <ul data-index="3" class="item">
  88. <li><a href="">日本核废水入海,西方环保人士为何失声</a></li>
  89. <li><a href="">双标“环保少女”背后“看不见的手”</a></li>
  90. <li><a href="">印尼潜艇载53人演练沉没,真实原因</a></li>
  91. <li><a href="">外交部再谈日本核废水排海</a></li>
  92. <li><a href="">印度疫情 医疗体系已经崩溃</a></li>
  93. </ul>
  94. </div>
  95. <script>
  96. // 事件代理实现导航的切换,获取元素
  97. const tab = document.querySelector(".tab");
  98. const items = document.querySelectorAll(".item");
  99. // 点选事件处理
  100. tab.onclick = (ev) => {
  101. // console.log(ev.currentTarget);
  102. // console.log(ev.target);
  103. // 1. 清空之前的激活样式,
  104. [...tab.children].forEach((item) => item.classList.remove("active")); //清空
  105. ev.target.classList.add("active"); //并将当前导航标签设置为激活状态
  106. // 2. 根据data-index来确定应该将哪个列表进行激活并显示出来
  107. items.forEach((item) => item.classList.remove("active")); //清空
  108. // console.log([...items].filter((item) => item.dataset.index === ev.target.dataset.index).pop());
  109. [...items]
  110. .filter((item) => item.dataset.index === ev.target.dataset.index)
  111. .pop()
  112. .classList.add("active"); //对应的列表激活
  113. };
  114. </script>
  115. </body>
  116. </html>
声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议