我们都知道使用<script>标签可以引入外部的JS文件,即使这个JS文件来自于其他的网站,比如我们引用存放在网络服务器上的jQuery框架。在这个过程中,我们已经实现跨域访问。像<script>标签这种本身具有跨域访问能力的标签还有<link>、<img>、<iframe>等。jsonp的实现原理就是利用<script>标签,实现了跨域访问。

先看一个例子:

先创建一个html文件,代码如下:

 <body>
<p>名字:<span id="name"></span></p>
<script>
function test(obj) {
document.getElementById("name").innerHTML = obj.name;
}
</script>
</body>

此时在浏览器打开这个文件,页面中只有“名字:”这三个字符。

现在创建一个JS文件,test.js,其中的代码如下:

 var person = {
name: "Jack",
age: 20
}
test(person);

通过<script>标签在html文件中引入这个test.js文件(添加到body结束标签之前):

 <script src="test.js"></script>

再在浏览器中打开html文件就会看到:

如果把这个test.js放在百度的服务器上,在淘宝的页面上有一个test函数声明,然后动态地创建一个<script>标签来引用这个test.js,那么在淘宝的页面上就可以显示来自百度的服务器的数据,这就是jsonp的原理。当然引用的不一定非要是js文件,也可以是php、.net等文件,只要在这些文件中事先写好相应的代码即可。

下面用聚合数据的天气预报接口和新浪的城市查询接口为例来介绍jsonp。

首先是新浪的城市查询接口。

新浪的城市查询接口是:

http://int.dpool.sina.com.cn/iplookup/iplookup.php?format=js

可以直接在浏览器中打开,发现是一个名为remote_ip_info的Javascript对象,

var remote_ip_info = {
"ret":1,
"start":-1,
"end":-1,
"country":"\u4e2d\u56fd",
"province":"\u6cb3\u5357",
"city":"\u8bb8\u660c",
"district":"",
"isp":"",
"type":"",
"desc":""
};

那么在本地的测试页面中可以使用这个接口获取所在的城市,代码如下:

 //获取当前城市
function getCity(url) {
var city = '';
//创建一个script标签
var script = document.createElement("script");
//设置script标签引用的url
script.setAttribute("src",url);
//将script标签添加到头部,也可以添加到其他地方
var head = document.getElementsByTagName('head')[0];
head.appendChild(script);
//如果script标签加载完成,获取城市
script.onload = function() {//script.onload不兼容IE8及以下版本
city = remote_ip_info["city"];
console.log(city);
}; //移除创建的script标签
head.removeChild(script);
} //该URL是新浪的获取当前城市的API,采用jasop方法获取数据
getCity("http://int.dpool.sina.com.cn/iplookup/iplookup.php?format=js");

下面是聚合数据的天气预报接口。

接口示例:http://op.juhe.cn/onebox/weather/query?cityname=%E6%B8%A9%E5%B7%9E&key=您申请的KEY

使用这个接口时至少要传入三个参数:

  1. cityname是要查询的城市名,可以用前面新浪的城市查询接口得到的数据。
  2. key是申请使用聚合数据天气预报接口时,给的APPKey。
  3. 另外还有一个callback参数,传入一个函数名,服务器会把查询后得到的数据拼接成函数调用的形式返回来,比如传入test函数名,则返回来test({"date":"2011-11-11","wind":"微风"}),所以要在测试页面声明好这个函数,以便对返回来的数据进行处理。

下面是代码:

html代码,将获得数据在页面中显示出来

 <p id="chuanyi"></p>
<p id="yundong"></p>
<p id="ziwaixian"></p>

获得天气情况数据的代码,原理与获取当前城市的原理一样,不同的是要事先指定回调函数,并将函数名加到url的末尾。

 function $(id) {
return document.getElementById(id);
} //指定回调函数
function callback(data) {
$("chuanyi").innerHTML = "穿衣指数:" + data.result.data.life.info.chuanyi;
$("yundong").innerHTML = "运动指数:" + data.result.data.life.info.yundong;
$("ziwaixian").innerHTML = "紫外线:" + data.result.data.life.info.ziwaixian;
} function getWeather(city) {
var url = 'http://op.juhe.cn/onebox/weather/query?cityname='+encodeURIComponent(city)+'&key=abbac0fc4fccbec34891de77bb1cfb4e&callback=callback';//该URL是聚合数据的天气预报API,采用jasop方法获取数据
console.log(encodeURIComponent(city));
var script = document.createElement("script");
script.setAttribute("src",url);
var head = document.getElementsByTagName('head')[0];
head.appendChild(script);
head.removeChild(script);
}

有了以上代码,还不能获取到天气数据,因为getWeather()函数还没有调用。为了能将获取到的城市数据传给getWeather()函数,要在getCity()函数内部script的onload事件处理程序中调用getWeather()函数。

下面是调用getWeather函数返回的数据,一大串:

 callback({
"reason":"successed!",
"result":{
"data":{
"pubdate":"2016-11-11",
"pubtime":"11:00:00",
"realtime":{
"city_code":"101180401",
"city_name":"许昌",
"date":"2016-11-11",
"time":"16:00:00",
"week":5,
"moon":"十月十二",
"dataUptime":1478853365,
"weather":{
"temperature":"15",
"humidity":"64",
"info":"多云",
"img":"1"
},
"wind":{
"direct":"南风",
"power":"3级",
"offset":null,
"windspeed":null
}
},
"life":{
"date":"2016-11-11",
"info":{
"chuanyi":["较冷","建议着厚外套加毛衣等服装。年老体弱者宜着大衣、呢外套加羊毛衫。"],
"ganmao":["较易发","天凉,昼夜温差较大,较易发生感冒,请适当增减衣服,体质较弱的朋友请注意适当防护。"],
"kongtiao":["较少开启","您将感到很舒适,一般不需要开启空调。"],
"xiche":["较适宜","较适宜洗车,未来一天无雨,风力较小,擦洗一新的汽车至少能保持一天。"],
"yundong":["较适宜","天气较好,但考虑气温较低,推荐您进行室内运动,若户外适当增减衣物并注意防晒。"],
"ziwaixian":["弱","紫外线强度较弱,建议出门前涂擦SPF在12-15之间、PA+的防晒护肤品。"]
}
},
"weather":[
{
"date":"2016-11-11",
"info":{
"day":["1","多云","17","","微风","06:53"],
"night":["0","晴","7","","微风","17:23"]
},
"week":"五",
"nongli":"十月十二"
},
{
"date":"2016-11-12",
"info":{
"dawn":["0","晴","7","无持续风向","微风","17:23"],
"day":["0","晴","17","","微风","06:54"],
"night":["1","多云","8","","微风","17:23"]
},
"week":"六",
"nongli":"十月十三"
},
{
"date":"2016-11-13",
"info":{
"dawn":["1","多云","8","无持续风向","微风","17:23"],
"day":["1","多云","17","","微风","06:55"],
"night":["0","晴","9","","微风","17:22"]
},
"week":"日",
"nongli":"十月十四"
},
{
"date":"2016-11-14",
"info":{
"dawn":["0","晴","9","无持续风向","微风","17:22"],
"day":["1","多云","17","","微风","06:56"],
"night":["2","阴","5","","微风","17:21"]
},
"week":"一",
"nongli":"十月十五"
},
{
"date":"2016-11-15",
"info":{
"dawn":["2","阴","5","无持续风向","微风","17:21"],
"day":["1","多云","13","","微风","06:57"],
"night":["1","多云","6","","微风","17:21"]
},
"week":"二",
"nongli":"十月十六"
}
],
"f3h":{
"temperature":[
{
"jg":"20161111170000",
"jb":"15"
},
{
"jg":"20161111200000",
"jb":"13"
},
{
"jg":"20161111230000",
"jb":"10"
},
{
"jg":"20161112020000",
"jb":"10"
},
{
"jg":"20161112050000",
"jb":"8"
},
{
"jg":"20161112080000",
"jb":"7"
},
{
"jg":"20161112110000",
"jb":"14"
},
{
"jg":"20161112140000",
"jb":"16"
},
{
"jg":"20161112170000",
"jb":"14"
}
],
"precipitation":[
{"jg":"20161111170000","jf":"0"},
{"jg":"20161111200000","jf":"0"},
{"jg":"20161111230000","jf":"0"},
{"jg":"20161112020000","jf":"0"},
{"jg":"20161112050000","jf":"0"},
{"jg":"20161112080000","jf":"0"},
{"jg":"20161112110000","jf":"0"},
{"jg":"20161112140000","jf":"0"},
{"jg":"20161112170000","jf":"0"}
]
},
"pm25":{
"key":"Xuchang",
"show_desc":0,
"pm25":{
"curPm":"50",
"pm25":"25",
"pm10":"51",
"level":1,
"quality":"优",
"des":"可正常活动。"
},
"dateTime":"2016年11月11日16时",
"cityName":"许昌"
},
"jingqu":"",
"jingqutq":"",
"date":"",
"isForeign":"0"
}
},
"error_code":0
})

这篇文章讲解的很详细:jsonp协议原理深度解析

(完)

跨域之jsonp的更多相关文章

  1. jQuery(三) javascript跨域问题(JSONP解决)

    加油~ --WH 一.什么是javascript跨域问题? 域:服务器域名,唯一标识(协议,域名,端口)必须保证一致,说明域相同 跨域:在一个服务器上,去访问另一个服务器上,并且得到另一个服务器返回回 ...

  2. 浏览器同源策略,跨域请求jsonp

    浏览器的同源策略 浏览器安全的基石是"同源政策"(same-origin policy) 含义: 1995年,同源政策由 Netscape 公司引入浏览器.目前,所有浏览器都实行这 ...

  3. 跨域Ajax -- jsonp和cors

    跨域Ajax - jsonp - cors 参考博客: http://www.cnblogs.com/wupeiqi/articles/5703697.html http://www.cnblogs. ...

  4. jquery跨域解决方案JSONP

    1.在互联网中我们的计算机是通过IP来定位的,但是IP比较难记忆,因此通过domain name(域名)来取代IP 2.什么是跨域? (1)默认浏览器为了安全问题,禁止了xmlhttprequest跨 ...

  5. Ajax跨域:Jsonp实例--百度搜索框下拉提示

    Ajax跨域:Jsonp实例--百度搜索框下拉提示 一.总结 一句话总结:a.找好接口:b.用script标签的src引入文件(json数据):c.定义及实现上一步引入文件中的函数 1.如何找到一个网 ...

  6. JS跨域:jsonp、跨域资源共享、iframe+window.name

    JS跨域:jsonp.跨域资源共享.iframe+window.name :https://www.cnblogs.com/doudoublog/p/8652213.html JS中的跨域 请求跨域有 ...

  7. 【记录】ajax跨域问题jsonp正确的使用方式

    最近遇到ajax请求跨域问题,解决方案用jsonp,现记录如下: //跨域请求jsonp封装 function doJsonPostCallBack(type, url, data,async, ca ...

  8. cors跨域和jsonp劫持漏洞 和 同源策略和跨域请求解决方案

    cors跨域和jsonp劫持漏洞: https://www.toutiao.com/a6759064986984645127/ 同源策略和跨域请求解决方案:https://www.jianshu.co ...

  9. 前端跨域解决方案: JSONP的通俗解说和实践

     对于前端开发者而言,跨域是一个绕不开的话题.只有真正明白了各种方案的工作机制,才能针对性地进行跨域方案选型.本文将以探索者的视角,试图用最通俗的语言对一种"鼎鼎大名"的跨域解决方 ...

  10. 跨域的jsonP

    1.出现原因:因为web中的同源策略(域名,协议,端口号)限制了跨域访问.   2.区别于json (个人理解)json是数据交换格式,jsonp是数据通信中的交互方式   3.jsonp的get与p ...

随机推荐

  1. solr_架构案例【京东站内搜索】(附程序源代码)

    注意事项:首先要保证部署solr服务的Tomcat容器和检索solr服务中数据的Tomcat容器,它们的端口号不能发生冲突,否则web程序是不可能运行起来的. 一:solr服务的端口号.我这里的sol ...

  2. 【开源】.Net 动态脚本引擎NScript

    开源地址: https://git.oschina.net/chejiangyi/NScript 开源QQ群: .net 开源基础服务  238543768 .Net 动态脚本引擎 NScript   ...

  3. Go结构体实现类似成员函数机制

    Go语言结构体成员能否是函数,从而实现类似类的成员函数的机制呢?答案是肯定的. package main import "fmt" type stru struct { testf ...

  4. css居中div的几种常用方法

    在开发过程中,很多需求需要我们居中一个div,比如html文档流当中的一块div,比如弹出层内容部分这种脱离了文档流等.不同的情况有不同的居中方式,接下来就分享下一下几种常用的居中方式. 1.text ...

  5. java中Action层、Service层和Dao层的功能区分

    Action/Service/DAO简介: Action是管理业务(Service)调度和管理跳转的. Service是管理具体的功能的. Action只负责管理,而Service负责实施. DAO只 ...

  6. BPM配置故事之案例3-参与者与数据自动加载

    这才过了两天,阿海又来了. 阿海:公司决定改进管理方式,以后物资申请的申请人和申请部门要写具体使用人的名字和部门了. 小明:不是要让我改回去吧? 阿海:那太麻烦了,你能不能把申请人改成选择,选好人自动 ...

  7. Toast显示图文界面——Android开发之路1

    Toast的多种使用方法 Toast其实是一个功能特别强大的组件,不仅仅可以吐司一个文本内容,还可以吐司图片以及图文混排的界面.具体用法如下: 第一种:简单的纯文本内容的吐司: Toast.makeT ...

  8. MySQL加密

    MySQL字段加密和解密 1.加密:aes_encrypt('admin','key') 解密:aes_decrypt(password,'key') 2.双向加密 通过密钥去加密,解密的时候的只有知 ...

  9. python select网络编程详细介绍

    刚看了反应堆模式的原理,特意复习了socket编程,本文主要介绍python的基本socket使用和select使用,主要用于了解socket通信过程 一.socket模块 socket - Low- ...

  10. RMS:Microsoft Office检测到您的信息权限管理配置有问题。有关详细信息,请与管理员联系。(转)

    原文:https://zhidao.baidu.com/question/435088233.html RMS有两种方式: 1.使用微软的服务器,这个是连接到微软的服务器上面做权限控制,在今年5月份之 ...