跨域通信及解决方法

在学习JavaScript的一些总结和经验,供大家参考和学习,同时也欢迎大家参与讨论。

温馨提醒:看这个章节我们必须了解一下同源策略和回调函数的概念;

JSONP

概述

jsonp是一种跨域通信的手段,利用 <script> 标签没有跨域限制的漏洞。通过 <script> 标签指向一个需要访问的地址并提供一个回调函数来接收数据当需要通讯时。

实现原理

场景:假如我要从跨域服务器获取一个用户省份userId=1234的信息,这条信息包括IP地址、城市和地区等;那么我如何使用JSONP跨域通信去获取?

例子:

本地服务器(http://localhost:80)下有一个文件Client.html

跨域服务器(http://server.example.com)下有一个服务端文件serverFile.php

Client.html

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
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>客户端</title>
</head>
<body>
<script>
// 回调函数
function handleCallback (response) {
alert("You're at IP address " + response.ip + " , which is in " + response.city + " , " + response.region_name);
}

function jsonp(url, jsonpCallback) {
let script = document.createElement('script')
script.async = true;
script.type = 'text/javascript';

if (script.readyState) { //支持IE的方法
script.onreadystatechange = function () {
if (script.readyState == "complete" || script.readyState == "loaded") {

}
}
} else { // w3c标准方法

}
script.src = url;
document.body.appendChild(script); // 将返回的JS代码`handleCallback(JSON数据)`标签插入DOM,解析执行
}

jsonp('http://server.example.com/userId/1234?jsonpCallback=handleCallback', handleCallback);
</script>
</body>
</html>

serverFile.php

这里只是举个例子,并不是说服务端的代码就是这样,只是给我们说明跨域服务器中服务端文件的作用。

  1. 接收到客户端的请求,请求地址带有回调函数的名称(handleCallback)
  2. 不管它是如何从数据库还是从哪里取得的数据,反正客户端就要userId为1234的信息
  3. 所以我就把数据处理完,放在$data里面
  4. 取得回调函数的名称(handleCallback)
  5. 输出回调函数名称(信息数据),像handleCallback({'ip': '212.24.234.43', 'city': '广州', 'region_name': '广东省'})
  6. 客户端接收到,并在客户端触发回调函数 handleCallback
1
2
3
4
5
6
7
8
9
10
11
12
<?php
$data = array( // 服务器先生成 JOSN 数据
'ip' => '212.24.234.43',
'city' => '广州',
'region_name' => '广东省'
);

$callback = $_GET['jsonpCallback']; // 取得回调函数的名称handleCallback
// 将 JOSN 数据直接以入参的方式,放置到 function 中,这样就生成了一段 js 语法的代码handleCallback(JOSN),返回给客户端。
echo $callback."(".json_encode($data).")";
// handleCallback({'ip': '212.24.234.43', 'city': '广州', 'region_name': '广东省'})
return;

参考:

https://lotabout.me/2016/JSONP/

https://yuchengkai.cn/docs/frontend/browser.html#jsonp

https://github.com/qianlongo/zepto-analysis/issues/4



文章标题: 跨域通信及解决方法
文章作者: 王奕聪,QQ:1301842163
许可协议: 知识共享许可协议
©署名-非商用-相同方式共享 4.0