博客列表 >JS 跨域请求

JS 跨域请求

滑稽...
滑稽...原创
2020年05月23日 15:40:50662浏览

同源策略

  • 域=协议名+主机名+端口号,只有这三部分相同才能称为是相同的域访问。
  • 多个页面的协议, 域名, 端口完全相同, 则认为他们遵循了”同源策略”
  1. http://www.baidu.com:80和ftp://www.baidu.com:80 不同域,协议不一样
  2. http://www.baidu.com:80和http://www.xiaomi.com:80 不同域,主机名不一样
  3. http://www.baidu.com:80和http://www.baidu.com:8080 不同域,端口号不一样
  4. http://www.baidu.com:80/a.html和http://www.baidu.com:80/b.js 同域
  • 同源策略是一种安全机制
  • 浏览器禁止通过脚本发起跨域请求, 如XMLHttpRequest,但是允许通知 html 标签属性跨域

跨域解决方法

1.CORS

  • CORS : 跨源资源共享 Cross-Origin Resource Sharing(CORS) 是一个新的 W3C 标准,它新增的一组HTTP首部字段,允许服务端其声明哪些源站有权限访问哪些资源。换言之,它允许浏览器向声明了 CORS 的跨域服务器,发出 XMLHttpReuest 请求,从而克服 Ajax 只能同源使用的限制。

  • 另外,规范也要求对于非简单请求,浏览器必须首先使用 OPTION 方法发起一个预检请求(preflight request),从而获知服务端是否允许该跨域请求,在服务器确定允许后,才发起实际的HTTP请求。

  • 当前域名是http://php11.cn,跨域请求域名是http://demo.net

  • 用AJAX,GET请求;

CORS.html
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>跨域请求-CORS</title>
  6. </head>
  7. <body>
  8. <button>跨域请求-CORS</button>
  9. <h2></h2>
  10. <script>
  11. var btn = document.querySelector('button');
  12. btn.addEventListener('click',function () {
  13. var xhr = new XMLHttpRequest();
  14. xhr.onreadystatechange = function () {
  15. if (xhr.readyState === 4 && xhr.status === 200) {
  16. console.log(xhr.responseText)
  17. document.querySelector('h2').innerHTML = xhr.responseText;
  18. }
  19. };
  20. xhr.open('GET','http://demo.net/jsonp_demo/CORS.php',true);
  21. xhr.send(null);
  22. },false);
  23. </script>
  24. </body>
  25. </html>
CORS.php
  1. <?php
  2. /**
  3. * Access-Control-Allow-Origin - 限定请求脚本的域名
  4. */
  5. header('Access-Control-Allow-Origin:http://php11.cn');
  6. echo '跨域请求成功';



2.JSONP

  • 常用的处理方式是JSONP。ajax请求不同域会出现跨域请求,无访问权限,但平时在HTML页面写的<script>、<link>这些标签的src属性是不受跨域请求限制的,于是,JSONP的策略就是服务器端可以动态生成JSON文件,把客户端需要的数据放到这个文件中,让客户端通过<script>标签的src属性来请求这个文件

  • 1.使用JSONP时,可以在页面中声明有这样的一个函数handle(),它将作为 JSONP 的回调函数处理作为函数参数传入的数据

    1. function handle(jsonData) {
    2. var data = jsonData;
    3. console.log(data);
    4. // 将接口返回的数据渲染到页面中
    5. var ul = document.createElement('ul');
    6. ul.innerHTML += "<li>" + data.name + "</li>";
    7. ul.innerHTML += "<li>邮箱: " + data.email + "</li>";
    8. document.body.appendChild(ul);
    9. }
  • 2.然后在url上传参
    1. script.src = "http://demo.net/jsonp_demo/JSONP.php?jsonp=handle&id=1";
  • 3.服务端在返回数据的时候,就会返回一端 Javascript 代码,在 Javascript代码中调用了回调函数,并且需要返回的数据作为回调函数的参数
    1. handle({name: "admin", email: "admin@qq.com"})
  • 4.最后页面成功加载了刚才指定路径的资源后,将会执行该 Javascript 代码,handle()函数将执行,这时一次跨域请求完成。

    JSON.HTML
    1. <!DOCTYPE html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <title>跨域请求-JSONP</title>
    6. </head>
    7. <body>
    8. <button>跨域请求-JSONP</button>
    9. <script>
    10. //1.准备好回调函数
    11. function handle(jsonData) {
    12. console.log(jsonData)
    13. // var data = JSON.parse(jsonData);
    14. var data = jsonData;
    15. console.log(data);
    16. // 将接口返回的数据渲染到页面中
    17. var ul = document.createElement('ul');
    18. ul.innerHTML += "<li>" + data.name + "</li>";
    19. ul.innerHTML += "<li>邮箱: " + data.email + "</li>";
    20. document.body.appendChild(ul);
    21. }
    22. //2.点击一个按钮发起一个基于JSONP的跨域请求
    23. var btn = document.querySelector('button');
    24. btn.addEventListener(
    25. "click",function () {
    26. var script = document.createElement("script");
    27. script.src = "http://demo.net/jsonp_demo/JSONP.php?jsonp=handle&id=1";
    28. document.head.appendChild(script);
    29. },
    30. false
    31. )
    32. </script>
    33. </body>
    34. </html>
    CORS.php
  1. <?php
  2. header('content-type:text/html;charset:utf-8');
  3. $callback = $_GET['jsonp'];
  4. $id = $_GET['id'];
  5. $users = [
  6. ['name'=>'admin','email'=>'admin@qq.com'],
  7. ['name'=>'html','email'=>'html@qq.com'],
  8. ['name'=>'html','email'=>'html@qq.com'],
  9. ];
  10. if (array_key_exists(($id-1),$users)) {
  11. $user = $users[$id-1];
  12. }
  13. echo $callback . '(' . json_encode($user) . ')';

总结

1 . JSONP 的优点是:它不像XMLHttpRequest对象实现的Ajax请求那样受到同源策略的限制;它的兼容性更好,在更加古老的浏览器中都可以运行。

JSONP 的缺点是:它只支持 GET 请求,而不支持 POST 请求等其他类型的 HTTP 请求

声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议