博客列表 >PHP大牛成长之路:JavaScript使用jsonp实现跨域请求及事件代理案例

PHP大牛成长之路:JavaScript使用jsonp实现跨域请求及事件代理案例

周Sir-BLOG
周Sir-BLOG原创
2020年08月16日 14:29:15630浏览

1、使用jsonp实现跨域请求

JSONP(JSON with Padding)是JSON的一种“使用模式”,可用于解决主流浏览器的跨域数据访问的问题。由于同源策略,一般来说位于 server1.example.com 的网页无法与不是 server1.example.com的服务器沟通,而 HTML 的<script> 元素是一个例外。利用 <script> 元素的这个开放策略,网页可以得到从其他来源动态产生的 JSON 资料,而这种使用模式就是所谓的 JSONP。用 JSONP 抓到的资料并不是 JSON,而是任意的JavaScript,用 JavaScript 直译器执行而不是用 JSON 解析器解析。

jsonp跨域示例

  • 实现功能:使用jsonp方法,在php.pro域名的demo1.html中输入用户id,跨域请求 php.io/jsonp.php 回调用户信息。

  • 数据表:

  • php.pro : demo1.html
  1. # demo1.html
  2. <!DOCTYPE html>
  3. <html lang="en">
  4. <head>
  5. <meta charset="UTF-8" />
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  7. <title>跨域请求-JSONP</title>
  8. <style>
  9. * {
  10. margin: 0;
  11. padding: 0;
  12. box-sizing: border-box;
  13. color: #555;
  14. }
  15. body {
  16. margin-top: 30px;
  17. }
  18. p {
  19. width: 80%;
  20. margin: 0 auto;
  21. }
  22. table {
  23. width: 80%;
  24. border: 1px solid;
  25. border-collapse: collapse;
  26. text-align: center;
  27. margin: 0 auto;
  28. }
  29. table caption {
  30. font-size: 1.2rem;
  31. margin: 10px;
  32. }
  33. table td,
  34. table th {
  35. border: 1px solid;
  36. padding: 5px;
  37. }
  38. </style>
  39. </head>
  40. <body>
  41. <p>
  42. <input type="text" name="userid" id="userid" placeholder="请输入ID" />
  43. <button>跨域请求-JSONP</button>
  44. </p>
  45. <table>
  46. <caption>
  47. 跨域请求结果:
  48. </caption>
  49. <thead>
  50. <tr>
  51. <td>id</td>
  52. <td>name</td>
  53. <td>email</td>
  54. </tr>
  55. </thead>
  56. <tbody id="user"></tbody>
  57. </table>
  58. <script>
  59. // 获取用户输入ID
  60. var id = document.getElementById("userid");
  61. // 获取提交按钮
  62. var btn = document.querySelector("button");
  63. // 监听事件
  64. btn.addEventListener("click", function () {
  65. // 动态生成script标签,发起jsonp请求
  66. var script = document.createElement("script");
  67. // url中的最后一个键值对,必须是一个回调
  68. script.src =
  69. "http://php.io/jsonp.php?id=" + id.value + "&action=getjsonp";
  70. // 将script便签放到head里
  71. document.head.appendChild(script);
  72. });
  73. function getjsonp(data) {
  74. var obj = JSON.parse(data);
  75. var table = document.createElement("tr");
  76. if(obj.error!=="null"){
  77. table.innerHTML += "<td>" + obj.id + "</td>";
  78. table.innerHTML += "<td>" + obj.username + "</td>";
  79. table.innerHTML += "<td>" + obj.email + "</td>";
  80. document.querySelector("#user").appendChild(table);
  81. }else{
  82. table.innerHTML += "<td colspan='3'>未找到数据</td>";
  83. document.querySelector("#user").appendChild(table);
  84. }
  85. }
  86. </script>
  87. </body>
  88. </html>
  • php.io/jsonp.php
  1. # jsonp.php
  2. // 防止出现乱码
  3. header('content-type:text/html;charset=utf-8');
  4. // id: 查询参数,这是可选
  5. $id = $_GET['id'];
  6. // 前端的回调函数的名称[必选]
  7. $callback = $_GET['action'];
  8. $id = trim($_GET['id']);
  9. $db = new PDO('mysql:host=localhost;dbname=php_pro', 'root', 'root');
  10. $sql="SELECT `id`,`username`,`email` FROM `users` WHERE `id`='{$id}'";
  11. $user = $db->query($sql)->fetch(PDO::FETCH_ASSOC);
  12. if(!empty( $user)){
  13. // 返回前端给回调的参数是一个json格式的数据
  14. // 生成js函数的调用语句
  15. echo $callback .' (\'' .json_encode($user) . '\')';
  16. }else{
  17. echo $callback .' (\'{"error":"null"}\')';
  18. }

2、事件代理示例

  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. <title>事件代理简单示例</title>
  7. <style>
  8. ul li {
  9. display: inline-block;
  10. margin:10px;
  11. }
  12. ul li:hover{
  13. background: #ccc;
  14. cursor: pointer;
  15. }
  16. div {
  17. width: 300px;
  18. height: 150px;
  19. background: #fff;
  20. position: absolute;
  21. top: 60px;
  22. left: 50px;
  23. border: 1px solid #ccc;
  24. padding: 20px;
  25. }
  26. </style>
  27. </head>
  28. <body>
  29. <ul>
  30. <li>item1</li>
  31. <li>item2</li>
  32. <li>item3</li>
  33. <li>item4</li>
  34. <li>item5</li>
  35. </ul>
  36. <div></div>
  37. <script>
  38. // 事件代理(事件委托):就是将子元素的事件,绑定在父级上执行。
  39. // 事件代理的好处:提高效率,不用循环为每个子元素绑定事件。
  40. var navs = document.querySelector("ul");
  41. navs.addEventListener("click", function (ev) {
  42. // alert("绑定:"+ev.currentTarget.nodeName +"\r\n触发:"+ev.target.nodeName);
  43. var div = document.querySelector("div");
  44. if(ev.target.nodeName==="LI") {
  45. div.innerHTML = "这是" + ev.target.innerHTML + "的内容";
  46. }
  47. });
  48. </script>
  49. </body>
  50. </html>

总结

jsonp跨域请求:

  • ① 前端定义一个函数,用来接收后台数据并渲染页面;比如:getjsonp(data)
  • ② 使用script的src属性以键值对方式将函数名传递给后台(便于后台拼接函数名)
  • ③ PHP后台接收到函数名, 将函数名拼接成函数表达式,函数参数使用json字符串;如 echo getjsonp({“id”:”111”,”name”:”peter”}
  • ④ 前台收到后台返回数据是一个函数表达式,就直接执行了;

jsonp跨域请求:相当于使用script引入PHP文件,在后台输出一个函数表达式欺骗浏览器以达到跨域的目的。
本来作业是要求获取商品信息的,但没有商品数据,使用用户数据模拟了。

事件代理:

  • 事件代理(事件委托):就是将子元素的事件,绑定在父级上执行。
  • 事件代理的好处:提高效率,不用循环为每个子元素绑定事件。
声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议