Blogger Information
Blog 63
fans 8
comment 8
visits 50061
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
PHP大牛成长之路:JavaScript使用jsonp实现跨域请求及事件代理案例
周Sir-BLOG
Original
631 people have browsed it

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文件,在后台输出一个函数表达式欺骗浏览器以达到跨域的目的。
本来作业是要求获取商品信息的,但没有商品数据,使用用户数据模拟了。

事件代理:

  • 事件代理(事件委托):就是将子元素的事件,绑定在父级上执行。
  • 事件代理的好处:提高效率,不用循环为每个子元素绑定事件。
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