Blogger Information
Blog 47
fans 1
comment 0
visits 53029
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
JS - 跨域请求 CORS 与 JSONP
晴天
Original
722 people have browsed it

1.跨域请求

  • CORS:跨域资源共享

  • CSRF:跨站请求伪造

1.1 JS 默认遵循同源策略

  • 多个页面的 协议,域名,端口 完全相同,则认为他们遵循了同源策略
  • 同源策略是一种安全机制
  • 浏览器禁止通过脚本发起跨域请求,如XMLHttpRequest但允许通过html标签属性跨域

php 文件

  1. <?php
  2. echo sha1(1);
  • 如果 php 文件与当前页在同一域名下则允许访问
  1. <button>跨站请求</button>
  2. <h2></h2>
  3. <script>
  4. // 按钮被单击跨站请求;
  5. var btn = document.querySelector("button");
  6. btn.addEventListener(
  7. "click",
  8. function () {
  9. // 创建异步请求
  10. var xhr = new XMLHttpRequest();
  11. // 监听返回值
  12. xhr.onreadystatechange = function () {
  13. if (xhr.readyState === 4 && xhr.status === 200) {
  14. console.log(xhr.responseText);
  15. document.querySelector("h2").innerHTML = xhr.responseText;
  16. }
  17. };
  18. // 初始化请求参数 同一域名
  19. xhr.open("get", "test.php", true);
  20. // 发送请求
  21. xhr.send(null);
  22. },
  23. false
  24. );

  • 如果不在
  1. // 初始化请求参数 不同域名
  2. xhr.open("get", "http://php11.edu/0522/test.php", true);

则会提示你禁止跨域

如果你非要跨域,也不是没有办法在 PHP 文件头部添加代码

  1. <?php
  2. header("Access-Control-Allow-Origin:http://js.edu");
  3. echo sha1(1);

跨域成功

2. JSONP

  • 同源策略禁止通过脚本发起跨域请求, 但是允许通过标签和属性发起一个跨域

  • 也就是 我们可以在<script src = ""></script> src 属性上下功夫,比如在 js 中写好方法,加载 src 时调用该方法并传参

php 部分

  1. <?php
  2. // 获取到id
  3. $id = $_GET['id'];
  4. $users = [
  5. '{"name":"Jerry", "email":"Jerry@qq.com"}',
  6. '{"name":"John", "email":"John@qq.com"}',
  7. '{"name":"Amy", "email":"Amy@qq.com"}',
  8. ];
  9. // 循环输出
  10. switch ($id) {
  11. case '1':
  12. echo "handle(". json_encode($users[0]).")";
  13. break;
  14. case '2':
  15. echo "handle(". json_encode($users[1]).")";
  16. break;
  17. case '3':
  18. echo "handle(". json_encode($users[2]).")";
  19. break;
  20. }

js 部分

  1. <button>JSONP跨站请求</button>
  2. <script>
  3. // 先创建一个方法
  4. function handle(jsonData) {
  5. console.log(jsonData);
  6. // 解析json
  7. var data = JSON.parse(jsonData);
  8. console.log(data);
  9. // 接接口返回值渲染到页面
  10. var ul = document.createElement("ul");
  11. ul.innerHTML += "<li>姓名:" + data.name + "</li>";
  12. ul.innerHTML += "<li>邮箱: " + data.email + "</li>";
  13. // 插入页面中
  14. document.body.appendChild(ul);
  15. }
  16. // 点击按钮发起基于JSONP的跨域请求
  17. var btn = document.querySelector("button");
  18. btn.addEventListener(
  19. "click",
  20. function () {
  21. // 创建一个标签
  22. var script = document.createElement("script");
  23. // 给标签的src赋值
  24. script.src = "http://php11.edu/0522/handle.php?id=1";
  25. // 将标签插入head中
  26. document.head.appendChild(script);
  27. },
  28. false
  29. );
  30. </script>

3. 基于 JSONP 简单做一个查询功能

index.html

  1. <!DOCTYPE html>
  2. <html lang="zh-CN">
  3. <head>
  4. <meta charset="UTF-8" />
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  6. <title>Document</title>
  7. <link rel="stylesheet" href="style.css" />
  8. </head>
  9. <body>
  10. <h2>查询员工信息</h2>
  11. <form action="" onsubmit="return false">
  12. <div>
  13. <input
  14. type="text"
  15. name="msg"
  16. placeholder="type your message"
  17. required
  18. />
  19. <select name="type">
  20. <option value="id">id</option>
  21. <option value="name">name</option>
  22. <option value="mobile">mobile</option>
  23. <option value="position">position</option>
  24. <option value="age">age</option>
  25. </select>
  26. </div>
  27. <button>查询</button>
  28. </form>
  29. </body>
  30. <script>
  31. // 获取按钮 和 表单
  32. var btn = document.querySelector("button");
  33. var select = document.querySelector("select");
  34. var input = document.querySelector("input");
  35. var head = document.querySelector("head");
  36. var body = document.querySelector("body");
  37. // 按钮被单击
  38. btn.addEventListener(
  39. "click",
  40. function () {
  41. var head_script = document.querySelectorAll("head > script");
  42. // 先检测head中有没有script
  43. if (head_script.length !== 0) {
  44. // 全部删除
  45. for (var i = 0; i < head_script.length; i++) {
  46. head.removeChild(head_script[i]);
  47. }
  48. }
  49. // 判断如果input有值插入script标签
  50. if (input.value !== ""){
  51. var script = document.createElement("script");
  52. script.src =
  53. "handle.php?action=" + select.value + "&value=" + encodeURIComponent(input.value);
  54. document.head.appendChild(script);
  55. }
  56. },
  57. false
  58. );
  59. // 创建函数
  60. function handle(jsonDate) {
  61. // 先检测有没有table 有的话删除
  62. var table = document.querySelectorAll("body > table");
  63. if (table.length !== 0) {
  64. // 全部删除
  65. for (var i = 0; i < table.length; i++) {
  66. body.removeChild(table[i]);
  67. }
  68. }
  69. // 创建table
  70. var table = document.createElement("table");
  71. // 首行
  72. table.innerHTML += "<tr><th>id</th><th>name</th><th>mobile</th><th>position</th><th>age</th></tr>";
  73. // 判断输出
  74. if (jsonDate.message === 0){
  75. // 0 = 没找到
  76. table.innerHTML += "<tr><td colspan='5'>"+jsonDate.value+"</td></tr>"
  77. }else {
  78. // 找到返回多维数组
  79. for (var i = 0; i < jsonDate.value.length; i++) {
  80. table.innerHTML += "<tr>" + "<td>" + jsonDate.value[i]['id'] + "</td>" + "<td>" + jsonDate.value[i]['name'] + "</td>" + "<td>" + jsonDate.value[i]['mobile'] + "</td>" + "<td>" + jsonDate.value[i]['position'] + "</td>" + "<td>" + jsonDate.value[i]['age'] + "</td>" + "</tr>"
  81. }
  82. }
  83. // 插入
  84. document.body.appendChild(table);
  85. }
  86. </script>
  87. </html>

handle.php

  1. <?php
  2. //先判断有没有get
  3. if (empty($_GET)){
  4. die("非法请求");
  5. }
  6. //获取GET值
  7. $action = $_GET['action'];
  8. //value值需要解码
  9. $value = urldecode($_GET['value']);
  10. //创建一个查询函数
  11. function sel($where,$value){
  12. $pdo = new PDO('mysql:host=localhost;dbname=php11.edu','php11.edu','php11.edu');
  13. $stmt = $pdo->prepare("SELECT * FROM `staffs` WHERE `{$where}`='{$value}'");
  14. $stmt->execute();
  15. // 获取多维数组
  16. $value = $stmt->fetchAll(PDO::FETCH_ASSOC);
  17. // 检测返回是否是空数组
  18. if (!empty($value)){
  19. return ["message"=>1,"value"=>$value];
  20. }else{
  21. return ["message"=>0,"value"=>"员工不存在或输入错误"];
  22. }
  23. }
  24. echo "handle(".json_encode(sel($action,$value)).")";

4. 总结

  • 意外发现php json编码后的数组刚好是js的对象字面量 前端不用解码 直接可以用
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