跨域访问资源

哪些东⻄属于资源?
js⽂件算吗?js⽂件肯定是算资源的,但是js⽂件是允许被跨域请求的。
css⽂件,jpg,png等。src属性的资源都是可以被跨域请求的。href资源⼤部分都是可以被
跨域请求的。

哪些资源算跨域请求的资源?

  1. 后端接⼝的数据。
  2. 其它域的cookie
  3. 其它域的缓存
    什么是其它的域?怎么样算跨域?
    ⻚⾯本身:有协议(http/https),域名,端⼝
    要请求的数据:http://www.baidu.com:80
    协议,域名,端⼝这三个,有任意⼀个不⼀样就算跨域。
    跨域这个⾏为,发⽣在哪⾥?
    答案:
  4. 即使跨域了(协议,域名,端⼝号有不⼀样的),请求也可以发出。
  5. 服务器端也是可以接收的。
  6. 服务器端也是可以正常处理的。
  7. 服务器端也是可以正常返回数据。
  8. 浏览器也能接收到这些数据。
  9. 接收到之后,发现当前⻚⾯的域和请求的域不同,所以判定为跨域。
  10. 我们的代码在这等着结果呢,但是因为浏览器判定跨域了,不会把结果传递给我们的代码。
    虽然跨域了,但是我们依然需要这个数据,怎么办?
    解决跨域问题:
  11. 后端(别⼈家的)配合我们进⾏跨域。
    pan.baidu.com ——> zhidao.baidu.com
    (1)JSONP(正常的情况,返回的数据都是JSON格式。JSONP是⼀种特殊的格式。)
    (2)后端设置Access-Control-Allow-Origin属性以⽀持跨域。
  12. 后端不配合我们进⾏跨域。
    (3)iframe(只能显示,不能控制)
    (4)通过后端代理(⾃⼰的后端)

image.png

jsonp原理

正常的Ajax是不可跨域的,用啦jsonp可以跨域,但jsonp返回格式与json不一样
如下图 使用script 请求jsonp的数据
image.png
这样跨域请求浏览器会报错
image.png
这个错误是因为jsonp的返回格式 asd()这是函数函数的形参是对象,而且用script的src属性请求回来的数据会被当做js代码执行所以asd就浏览器当做js代码执行,由于我没有定义asd这个函数所以才会报出not defined 这个错误 ,但是数据是请求到啦
image.png

  1. //因为我想从一个接口获取一个数据
  2. //但是这个接口和当前页面不是同源的。(也就是跨域了)
  3. //但是这个接口是支持JSONP的。
  4. //script标签,有src属性,所以可以发出网络请求
  5. //script标签,虽然可以引用其他域的资源,浏览器不限制。
  6. //但是,浏览器会将返回的内容,作为js代码执行。
  7. //asd({"status":"ok","msg":"Hello! There is DuYi education!"})
  8. //相当于调用了asd方法,传入了一个json对象作为参数。
  9. //JSONP原理:
  10. //1. 判断请求与当前页面的域,是否同源,如果同源则发送正常的ajax,就没有跨域的事情了。
  11. //2. 如果不同源,生成一个script标签
  12. //3. 生成一个随机的callback名字,还得创建一个名为这个的方法。
  13. //4. 设置script标签的src,设置为要请求的接口。
  14. //5. 将callback作为参数拼接在后面。
  15. //============以上是前端部分================
  16. //6. 后端接收到请求后,开始准备要返回的数据
  17. //7. 后端拼接数据,将要返回的数据用callback的值和括号包裹起来
  18. // 例如:callback=asd123456,要返回的数据为{"a":1, "b":2},
  19. // 就要拼接为:asd123456({"a":1, "b":2});
  20. //8. 将内容返回。
  21. //============以上是后端部分================
  22. //9. 浏览器接收到内容,会当做js代码来执行。
  23. //10. 从而执行名为asd123456的方法。这样我们就接收到了后端返回给我们的对象。
  24. var $ = {
  25. ajax: function (options) {
  26. var url = options.url;
  27. var type = options.type;
  28. var dataType = options.dataType;
  29. //判断是否同源(协议,域名,端口号)
  30. //获取目标url的域
  31. var targetProtocol = "";//目标接口的协议
  32. var targetHost = "";//目标接口的host,host是包涵域名和端口的
  33. //如果url不带http,那么访问的一定是相对路径,相对路径一定是同源的。
  34. if (url.indexOf("http://") == 0 || url.indexOf("https://") == 0) {
  35. var targetUrl = new URL(url);
  36. targetProtocol = targetUrl.protocol;
  37. targetHost = targetUrl.host;
  38. } else {
  39. targetProtocol = location.protocol;
  40. targetHost = location.host;
  41. }
  42. //首先判断是否为jsonp,因为不是jsonp不用做其他的判断,直接发送ajax
  43. if (dataType == "jsonp") {
  44. //要看是否同源
  45. if (location.protocol == targetProtocol && location.host == targetHost) {//表示同源
  46. //此处省略。因为同源,jsonp会当做普通的ajax做请求
  47. } else {//不同源,跨域
  48. //随机生成一个callback
  49. var callback = "cb" + Math.floor(Math.random() * 1000000);
  50. //给window上添加一个方法
  51. window[callback] = options.success;
  52. //生成script标签。
  53. var script = document.createElement("script");
  54. if (url.indexOf("?") > 0) {//表示已经有参数了
  55. script.src = url + "&callback=" + callback;
  56. } else {//表示没有参数
  57. script.src = url + "?callback=" + callback;
  58. }
  59. script.id = callback;
  60. document.head.appendChild(script);
  61. }
  62. }
  63. }
  64. }
  65. //http://developer.duyiedu.com/edu/testJsonp?callback
  66. $.ajax({
  67. url: "http://developer.duyiedu.com/edu/testJsonp",
  68. type: "get",
  69. dataType: "jsonp",
  70. success: function (data) {
  71. console.log(data);
  72. }
  73. });