什么是跨域
ajax请求具有同源策略(1.同协议。2.同域名/同IP。3.同端口号)。其中三项任何一项不满足都会发生跨域问题
jsonp原理
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<img src="https://t7.baidu.com/it/u=1951548898,3927145&fm=193&f=GIF">
</html>
我们在本地打开这个页面,图片会加载出来。同样的我们可以通过<script></script>
标签来引入外部的js文件。src并没有同源问题。我们就可以将数据放在一个js文件里,将数据作为一个函数打的实参,然后在页面中,通过该函数的形参来接收这个数据。示例:
js文件:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script> //预先声明函数准备形参准备接收实参 function start(data) {
alert(data); } </script>
<!-- 引入后函数执行将实参传到形参中去,即将数据传送过去 -->
<script src="test.js"></script>
</head>
<body>
</html>
jsonp功能实现
从原理上看,我们还有两个问题
-
1)如何控制什么时候开始下载数据
-
2)src地址的文件后缀名只能传.js吗?
首先看第一个问题
我们是通过script标签来引入数据,所以我们只需要决定什么时候创建这个script标签就能决定什么时候下载改数据。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script> function start(data) {
alert(data); } </script>
<!-- -->
<!-- <script src="test.js"></script> -->
<script> window.onload = function() {
var bt1 =document.getElementById("bt1"); bt1.onclick = function() {
//点击按钮后创建一个script标签 var script = document.createElement("script"); script.src = "test.js"; document.body.appendChild(script); } } </script>
</head>
<body>
<button id="bt1">下载数据</button>
</body>
</html>
第二个问题
文件的后缀名有什么作用?
文件的后缀名只会告诉计算机用什么方式打开,对于计算机来说只有0和1,所以就算我们将test.js
的后缀名该位.mp4
等其它的格式,一样可以拿到我们的数据。
所以我们可以引入任何类型的文件,只要文件里面是我么你想要的代码。
根据上述过程总结出jsonp跨域的步骤
- 1.先声明一个函数,该函数要有一个形参
- 2.在需要下载数据的时候动态创建script标签,并设置script标签的src
- 3.script标签插入完成后,执行声明的函数,将数据传到函数的形参中。
jsonp跨域传的数据必须是函数调用的格式。
天气查询案例
我们先看效果图
首先我们得有一个接口来获取数据,提供一个链接,天气数据接口
将API地址复制,然后在浏览器中打开会出现这样一段数据
我们也可以通过get请求直接在地址后面拼接?city=武汉
,拿到想要的城市的天气。
然后我们再继续在后面拼接
访问的数据也发生变化,成为了函数调用
这样我们就能拿到想要的数据,接下来将数据展现在页面上
通过https://www.bejson.com/将数据格式化以下方便我们查看
我们只需要将weather里面的数组取出来放在表格中就可以了
我们在请求的时候同样的动态创建一个script标签并设置它的src
var script = document.createElement("script");
script.src = `https://query.asilu.com/weather/baidu/?city=${
city.value}&callback=show`;
document.body.appendChild(script);
然后通过show()函数的形参接收数据,然后取出我们想要的内容,最后将内容添加的页面上去
function show(data) {
var t1 = document.getElementById("t1");
var info = document.getElementById("info");
info.innerHTML = data.city;
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>`;
}
t1.innerHTML = str;
}
整个页面使用的是bootstrap,完整代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>天气查询</title>
<link rel="stylesheet" href="bootstrap.css">
<script> function show(data) {
var t1 = document.getElementById("t1"); var info = document.getElementById("info"); info.innerHTML = data.city; 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>`; } t1.innerHTML = str; } </script>
<script> window.onload = function () {
var search = document.getElementById("search"); var city = document.getElementById("city"); search.onclick = function () {
if (!city.value) {
alert("请输入城市名"); } else {
var script = document.createElement("script"); script.src = `https://query.asilu.com/weather/baidu/?city=${
city.value}&callback=show`; document.body.appendChild(script); } } } </script>
</head>
<body>
<div class="container">
<div class="panel panel-default">
<div class="panel-heading">
<h2>天气查询---当前城市为:<span id="info"></span></h2>
<span id="info"></span>
</div>
<div class="panel-body">
<div class="form-group">
<label for="city">城市名字</label>
<input type="text" class="form-control" id="city">
</div>
<button type="button" class="btn btn-primary form-control" id="search">点击查询</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>