JSONP 的原理、理解 与 实例分析
JSONP 的基本原理
JSONP(JSON with Padding)是一种跨域数据访问技术,在 A 网站的页面中向 B 网站请求数据时,由于浏览器的同源策略限制,不允许直接访问不同域下的数据。但是,通过在 A 网站中添加一个 script 标签,请求 B 网站中的数据,并采用特定的回调函数对数据进行处理。B 网站返回的数据包裹在回调函数中,从而实现跨域数据访问。
以访问百度搜索接口(http://suggestion.baidu.com/su?wd=string)为例,URL 中 wd=string 表示搜索框中输入的关键字,通过 JSONP 技术实现跨域数据访问的代码如下:
function searchBaidu(){
var input = document.getElementById("keyword").value;
var url = "http://suggestion.baidu.com/su?wd=" + input + "&cb=handleData";
var script = document.createElement("script");
script.src = url;
document.body.appendChild(script);
}
function handleData(data){
// 处理数据
}
在上述代码中,searchBaidu 函数通过创建一个 script 标签来向百度搜索接口请求数据,其中每个 script 标签都有一个 src 属性来指定请求的 URL。返回的数据包裹在回调函数 handleData 中进行处理。
JSONP 的实例分析
示例 1:从 Flickr API 中获取照片
以从 Flickr API 中获取照片为例,API 文档地址:https://www.flickr.com/services/api/flickr.photos.search.html
- 在个人网站上添加一个搜索框和一个搜索按钮。
<div>
<input type="text" id="keyword">
<input type="button" value="搜索" onclick="searchPhotos()">
</div>
- 创建一个函数 searchPhotos,在函数中创建一个 script 标签,向 Flickr API 发送请求。同时,在发送请求之前,需要生成一个 callback 函数的名称,并将其作为参数添加到 URL 中。返回的数据将会包裹在回调函数中。
function searchPhotos(){
var input = document.getElementById("keyword").value;
var apiKey = "9e1e143ef32b2c960dc37ca005f6da7e";
var method = "flickr.photos.search";
var url = "https://www.flickr.com/services/rest/?method=" + method
+ "&api_key=" + apiKey + "&text=" + input + "&format=json&jsoncallback=handleData";
var script = document.createElement("script");
script.src = url;
document.body.appendChild(script);
}
function handleData(data){
console.log(data);
// 打印数据
}
在上述代码中,生成的 URL 如下所示:
https://www.flickr.com/services/rest/?method=flickr.photos.search&api_key=9e1e143ef32b2c960dc37ca005f6da7e&text=sky&format=json&jsoncallback=handleData
在这个 URL 中,jsoncallback 的值指定回调函数的名称,因此 AJAX 请求的返回值将是一个回调函数调用的完整代码块。
- 在服务器端,返回 JSON 数据,并根据请求中指定的 callback 函数名,返回生成该回调函数调用的代码块。
例如,在 PHP 中返回 JSON 数据并使用 $_GET["callback"] 获取回调函数名,实现代码如下:
<?php
header('Content-type: application/javascript');
$data = array("name" => "Ricky", "age" => "20");
$callback = $_GET["callback"];
echo $callback . "(" . json_encode($data) . ");";
?>
在返回数据前,使用 $_GET["callback"] 获取回调函数名,构建一个类似于下面的 JSON 数据:
{
"name": "Ricky",
"age": "20"
}
并在返回数据时,将该数据和回调函数名拼接在一起,返回生成该回调函数调用的代码块,如下所示:
handleData({"name":"Ricky","age":"20"});
这样的返回数据将直接放在 script 标签中,浏览器将以脚本文件的形式执行。
示例 2:通过淘宝 API 查询IP地址所在地
以通过淘宝 API 查询 IP 地址所在地为例,API 文档地址:https://ip.taobao.com/instructions.php
- 在个人网站上添加一个文本框和一个按钮。
<div>
<input type="text" id="ip">
<input type="button" value="查询" onclick="searchIP()">
</div>
- 创建一个函数 searchIP,在函数中创建一个 script 标签,向淘宝 API 发送请求。同时,在发送请求之前,需要生成一个 callback 函数的名称,并将其作为参数添加到 URL 中。返回的数据将会包裹在回调函数中。
function searchIP(){
var input = document.getElementById("ip").value;
var url = "https://ip.taobao.com/outGetIpInfo?ip=" + input + "&accessKey=alibaba-inc&callback=handleData";
var script = document.createElement("script");
script.src = url;
document.body.appendChild(script);
}
function handleData(data){
console.log(data);
// 打印数据
}
在上述代码中,生成的 URL 如下所示:
https://ip.taobao.com/outGetIpInfo?ip=202.204.80.112&accessKey=alibaba-inc&callback=handleData
在这个 URL 中,callback 的值指定回调函数的名称,因此 AJAX 请求的返回值将是一个回调函数调用的完整代码块。
- 在服务器端,返回 JSON 数据,并根据请求中指定的 callback 函数名,返回生成该回调函数调用的代码块。
例如,在 PHP 中返回 JSON 数据并使用 $_GET["callback"] 获取回调函数名,实现代码如下:
<?php
header('Content-type: application/javascript');
$data = array("ip" => "202.204.80.112", "city" => "南京");
$callback = $_GET["callback"];
echo $callback . "(" . json_encode($data) . ");";
?>
在返回数据前,使用 $_GET["callback"] 获取回调函数名,构建一个类似于下面的 JSON 数据:
{
"ip": "202.204.80.112",
"city": "南京"
}
并在返回数据时,将该数据和回调函数名拼接在一起,返回生成该回调函数调用的代码块,如下所示:
handleData({"ip":"202.204.80.112","city":"南京"});
这样的返回数据将直接放在 script 标签中,浏览器将以脚本文件的形式执行。
总结
通过使用 jQuery.ajax 和 JSONP 技术可以轻松实现跨域数据访问。JSONP 技术通过创建一个 script 标签,在浏览器中执行 JavaScript 代码的方式来接收返回的数据。在回调函数中对数据进行处理,可以使数据不受跨域限制而被调用。
其中,回调函数名称是在请求时候由客户端生成的,需要服务器端返回执行该回调函数是完整的 JavaScript 代码。如果服务器端不能返回正确的回调函数,则会发生错误。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JSONP 的原理、理解 与 实例分析 - Python技术站