Blogger Information
Blog 43
fans 1
comment 0
visits 33801
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
跨域请求的原理(CORS/JSONP)
蔚蓝世纪
Original
773 people have browsed it

如果你正在访问一个网站,而你登录以后,又去浏览其他网站。如果其他网站可以读取到你之前正在访问的网站的Cookie,你又没有退出登录,那么其他网站就可以冒充你,为所欲为。这个过程,就叫做跨站请求伪造。那么如何避免这种不安全的操作呢,我们可以使用“同源策略”。“同源策略”的目的,是为了保证用户信息的安全,防止恶意的网站窃取数据。目前,所有浏览器都实行这个政策。即A网页设置的 Cookie,B网页不能打开,除非这两个网页”同源”。所谓”同源”指的是”三个相同”:

  1. 协议相同
  2. 域名相同
  3. 端口相同

举例来说,https://www.php.cn/course/type/3.html这个网址,协议是https://,域名是www.php.cn,端口是80(默认端口可以省略)。它的同源情况如下:

  1. https://www.php.cn/wenda.html:同源
  2. http://php.cn/other.html:不同源(协议不同)
  3. https://www.php.net/other.html:不同源(域名不同)
  4. https://www.php.cn:81/course/type/3.html:不同源(端口不同)

同源策略规定,AJAX请求只能发给同源的网址,否则就报错。我们可以用以下两种方法规避这个限制。

一、跨域资源共享 CORS。

CORS是一个W3C标准,全称是”跨域资源共享”(Cross-origin resource sharing)。它允许浏览器向跨域服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。CORS需要浏览器和服务器同时支持。整个CORS通信过程,都是浏览器自动完成,不需要用户参与。

  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>Document</title>
  7. </head>
  8. <body>
  9. <button>跨域请求-CORS</button>
  10. <h2></h2>
  11. <script>
  12. var btn = document.querySelector("button");
  13. btn.addEventListener(
  14. "click",
  15. function () {
  16. // 1. 创建Ajax对象
  17. var xhr = new XMLHttpRequest();
  18. // 2. 监听请求
  19. xhr.onreadystatechange = function () {
  20. if (xhr.readyState === 4 && xhr.status === 200) {
  21. console.log(xhr.responseText);
  22. document.querySelector("h2").innerHTML = xhr.responseText;
  23. }
  24. };
  25. // 3. 初始化请求参数
  26. xhr.open("GET", "http://php.edu/0522/test1.php", true);//"test1.php"在另外一个服务器上
  27. // 4. 发送请求
  28. xhr.send(null);
  29. },
  30. false
  31. );
  32. </script>
  33. </body>
  34. </html>

输出效果:

test1.php

  1. <?php
  2. header('Access-Control-Allow-Origin:http://js.edu');
  3. header('content-type:text/html;charset-utf-8');
  4. echo '跨域脚本返回的数据';
  5. flush();

二、跨域资源共享 JSONP。

JSONP是服务器与客户端跨域通信的常用方法。它的基本思想是,网页通过添加一个<script>元素,向服务器请求JSON数据,这种做法不受同源策略限制,服务器收到请求后,将数据放在一个指定名字的回调函数里传回来。

  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>跨域请求-JSONP</title>
  7. </head>
  8. <body>
  9. <button>跨域请求-JSONP</button>
  10. <script>
  11. // 1. 准备好回调处理函数
  12. function handle(jsonData) {
  13. console.log(jsonData);
  14. var data = JSON.parse(jsonData);
  15. console.log(data);
  16. // 将接口返回的数据渲染到页面中
  17. var ul = document.createElement("ul");
  18. ul.innerHTML += "<li>" + data.title + "</li>";
  19. ul.innerHTML += "<li>姓名:" + data.user.name + "</li>";
  20. ul.innerHTML += "<li>邮箱:" + data.user.email + "</li>";
  21. document.body.appendChild(ul);
  22. }
  23. // 2. 点击按钮发起一个基于JSONP的跨域请求
  24. var btn = document.querySelector("button");
  25. btn.addEventListener(
  26. "click",
  27. function () {
  28. var script = document.createElement("script");
  29. script.src = "http://php.edu/0522/test2.php?jsonp=handle&id=3";
  30. document.head.appendChild(script);
  31. },
  32. false
  33. );
  34. </script>
  35. </body>
  36. </html>

test2.php

  1. <?php
  2. //这里返回的是json,json只支持utf8
  3. header('content-type:text/html;charset=utf-8');
  4. $callback = $_GET['jsonp'];
  5. $id = $_GET['id'];
  6. //模仿接口,根据查询条件返回不同的内容
  7. $users = [
  8. 0=>'{"name":"admin","email":"admin@php.cn"}',
  9. 1=>'{"name":"lulu","email":"lulu@php.cn"}',
  10. 2=>'{"name":"anna","email":"anna@php.cn"}',
  11. ];
  12. if (array_key_exists(($id-1),$users)) {
  13. $user = $users[$id-1];
  14. }
  15. $json = '{
  16. "title":"用户信息表",
  17. "user":'.$user.'
  18. }';
  19. echo $callback . '('. json_encode($json) . ')';

输出效果:

三、总结

1.同源策略是针对脚本发出请求的,不针对标签,所以比如img标签可以跨域。
2.JSONP只能发送GET请求,而CORS支持所有类型的HTTP请求。
3.实现CORS通信的关键是服务器,只要服务器实现了CORS接口,就可以跨域通信。
4.CORS与JSONP的使用目的相同,但是比JSONP更强大。
5.JSONP支持老式浏览器,以及可以向不支持CORS的网站请求数据。

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
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!