详细内容
1.认识JSONP跨域
1.1什么是跨域
跨域,是指浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对JavaScript实施的安全限制。无法跨域是浏览器对于用户安全的考虑,如果自己写个没有同源策略的浏览器,完全不用考虑跨域问题了。是浏览器的锅,对。
同源策略限制了一下行为:
Cookie、LocalStorage 和 IndexDB 无法读取
DOM 和 JS 对象无法获取
Ajax请求发送不出去
1.2什么是同源策略
所谓同源是指,域名,协议,端口均相同
浏览器执行javascript脚本时,会检查这个脚本属于哪个页面,如果不是同源页面,就不会被执行。
1.3跨域的解决办法
- 修改ajax同源协议(不建议,危险)
- 委托php文件中转跨域
- JSONP
2.JSONP办法解决跨域
注意:JSONP只支持GET请求,不支持POST请求
ajax请求受同源策略影响,不允许进行跨域请求,而script标签src属性中的链接却可以访问跨域的js脚本,利用这个特性,服务端不再返回JSON格式的数据,而是返回一段调用某个函数的js代码,在src中进行了调用,这样实现了跨域。
简单举例:
1 2 3 4 5 6 7 8 9 10
| <-- 服务端 一个js文件 --> download("I am String!")
<-- 客户端 --> <script> function download(data){ alert("下载数据"+data); } </script> <script src="28.demo.js"></script>
|
上面的例子有2个问题:
- 在需要的时候加载数据
- 能否引入除.js文件以外的其他路径
第一个问题可以通过动态插入script标签解决
第二个问题,其实对于计算机来说,文件后缀是没有任何用处的。只决定优先用什么软件打开他。
所以JSONP跨域使用步骤为:
- 先去声明一个函数,这个函数有一个形参
- 在需要下载数据的时候,动态创建script标签,将标签src属性设置成下载数据的链接
- 当script插入到页面上时,就会调用封装好的函数将需要的数据传过来
如果是一个支持JSONP参数的接口,我们可以在网址后面拼接上&callback=download,使得数据为JSONP格式,得到的字符串可以用https://www.bejson.com/可视化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
| <!DOCTYPE html> <html lang="en">
<head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <link rel="stylesheet" href="bootstrap-3.3.7-dist/css/bootstrap.min.css"> <link rel="stylesheet" href="bootstrap-3.3.7-dist/css/buttons.css"> <script> function download(data) { var oT1=document.getElementById("t1"); var oInfo=document.getElementById("info");
oInfo.innerHTML=`城市:${data.city},PM2.5:${data.pm25}`; var arr = data.weather; var str=``; for(var i=0;i<arr.length;i++){ str+=`<tr> <td>${arr[i].date}</td> <td>${arr[i].weather}</td> <td>${arr[i].wind}</td> <td>${arr[i].temp}</td> </tr>` } oT1.innerHTML=str; } </script> <script> window.onload = function () { var oSearch = document.getElementById("search"); var oCity = document.getElementById("city"); oSearch.onclick = function () { if (!oCity.value) { alert("请输入城市名字"); } else { var oScript = document.createElement("script"); oScript.src = `https://api.asilu.com/weather/?city=${oCity.value}&callback=download`; document.body.appendChild(oScript); } } } </script> </head>
<body> <div class="container"> <div class="panel panel-primary"> <div class="panel-heading"> <h2>天气查询</h2> <span id="info"></span> </div> <div class="panel-body"> <div class="form-group"> <label for="city">城市名字:</label> <input id="city" type="text" class="form-control"> </div> <button id="search" class="button button-3d button-action button-pill form-control">查询该城市的天气</button> </div> <div class="panel-footer"> <table class="table table-bordered table-hover"> <thead> <tr> <th>日期</th> <th>天气</th> <th>风向</th> <th>气温</th> </tr> </thead> <tbody id="t1"> </tbody> </table> </div> </div> </div> </body>
</html>
|