事件背景:

某个站点分为静态产品介绍页面(或由于某原因需要静态化),和一个独立的在线应用程序。静态产品页面属于www.a.com下,而在线应用程序作为一个相对独立的系统存在于app.a.com上。

在www.a.com上需要显示在线应用程序(app.a.com)中用户的登录状态及简单的用户信息。由于需要实时的在静态页面中显示用户登录状态,在线应用程序提供了一个用户接口来输出当前用户的登录信息,静态页面采用ajax方式动态获取。

问题在于www.a.com和app.a.com分属于不同子域,无法通过ajax直接进行通信。~~通信协议 域名 端口号都相同才认为是同源

思路分析:

由于同源策略的限制,XMLHttpRequest只允许请求当前源(包含域名、协议、端口)的资源。

如众周知,script标签经常被用来加载不同域下的资源,例如在www.a.com可以使用http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js这个js文件,可以绕过同源策略。~~~script标签可以不受同源策略限制,加载不同域下的资源

同样的,可以通过使用script标签来进行跨域请求,但是怎么获取异域源返回的数据呢?

有这样一种方式:如果请求的这个远程数据本身就是一段可执行的js,那么这些js会被执行(相当于eval)。即,若在www.a.com中存在一个showUserStatus()的js函数,它的作用是在www.a.com显示当前用户状态,只要给它传递当前用户的状态数据就可以了。那么利用script标签请求的app.a.com中,输出数据为:showUserStatus(data),那么将会执行www.a.com中的showUserStatus(),用户当前的状态就在静态页面上显示了。

使用JSON来传递javascript对象是一种最简单的方式了,这样的跨域通讯方式称为JSONP

解决方案:

1. 静态页面上的js:


<script type="text/javascript">
function showUserStatus(data) {
alert(data.txt);
}
</script>
<!--将函数名showUserStatus传递过去-->
<script type="text/javascript" src="http://app.a.com/userStatus.php?callback=showUserStatus"></script>

2. 远程php接口:


$get = $_GET;
$rtData = array(
'uID' => 10000,
'name' => 'Zhangsf',
'txt' => 'Welcome ZhangSanFeng',
); // 获取传递来的函数名,并拼凑完整的函数执行体
echo $get['callback'] .'('. json_encode($rtData) .')';

这里输出的格式为:

showUserStatus({"uID":10000,"name":"Zhangsf","txt":"Welcome ZhangSanFeng"})

可以看出,输出的是一个可执行的js函数体。

总结:

需要注意的是:JSONP实际上是一种脚本注入(Script Injection)方式,存在一定的安全隐患。

jQuery的书写方法如下:


var url = 'http://app.a.com/userStatus.php?callback=?'; $.getJSON(url, function(data){
alert(data.txt)
});

抓包发现会产生类似于http://app.a.com/userStatus.php?type=json&callback=jsonp1261223089741&_=1261223089747的请求地址,问号被替换为一个带时间戳的回调函数名。

转: ajax跨域之JSONP的更多相关文章

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

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

  2. Ajax跨域:Jsonp原理解析

    推荐先看下这篇文章:JS跨域(ajax跨域.iframe跨域)解决方法及原理详解(jsonp) JavaScript是一种在Web开发中经常使用的前端动态脚本技术.在JavaScript中,有一个很重 ...

  3. 【JS跨域请求】Ajax跨域请求JSONP

    前两天被问到ajax跨域如何解决,还真被问住了,光知道有个什么jsonp,迷迷糊糊的没有说上来.抱着有问题必须解决的态度,我看了许多资料,原来如此... 为何一直知道jsonp,但一直迷迷糊糊的不明白 ...

  4. JQuery实现Ajax跨域访问--Jsonp原理

    JavaScript是一种在Web开发中经常使用的前端动态脚本技术.在JavaScript中,有一个很重要的安全性限制,被称为“Same-Origin Policy”(同源策略).这一策略对于Java ...

  5. ajax跨域请求のJSONP

    简单说了一下,JSON是一种基于文本的数据交换方式,或者叫做数据描述格式. JSON的优点: 1.基于纯文本,跨平台传递极其简单: 2.Javascript原生支持,后台语言几乎全部支持: 3.轻量级 ...

  6. AJAX跨域与JSONP的一点实践经验

    前几个周,项目中遇到了AJAX跨域的问题,然后找资料解决了. 首先要说明一点,关于AJAX的跨域原理和实践,我的经验还是比较少的,我只是大致看了下网上的资料,结合自己的理解,找到了解决办法,暂时不去仔 ...

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

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

  8. Ajax跨域:jsonp还是CORS

    跨域一般用jsonp,兼容性比较好.CORS是html5最新的XHR第二版本,不支持IE8,IE9,对移动端的支持非常好.但是考虑项目后期这部分会转到同域名下,而且网址不需要支持ie8,ie9,所以我 ...

  9. jfinal 解决ajax 跨域访问--jsonp

    JavaScript出于安全方面的考虑,不允许跨域调用其他页面的对象.简单地理解就是因为JavaScript同源策略的限制,a.com 域名下的 js无法操作b.com或是c.a.com域名下的对象. ...

  10. AJAX 跨域请求 - JSONP获取JSON数据

    Asynchronous JavaScript and XML (Ajax ) 是驱动新一代 Web 站点(流行术语为 Web 2.0 站点)的关键技术.Ajax 允许在不干扰 Web 应用程序的显示 ...

随机推荐

  1. CNZZ公告:近期无法获取百度关键词

    今天登录cnzz网站统计,出现一条公告,说是“关于近期无法获取百度关键词的公告”,内容如下: 近日部分用户反馈百度搜索词流量出现不同程度的下降.经排查,是由于百度搜索引擎调整了URL规则,取消了来源U ...

  2. 文件下载Demo

    知识点: //获取用户要下载的资源的名称        string name=context.Request.Params["downloadName"];        //设 ...

  3. CSS–Some Structure

    Some Structure About CSS Layout Position,Layer[层次] Box Model Visual Formatting Model BFC[block forma ...

  4. LINQ实现行列转换

    用SQL语句实现行列转换很容易,但也有时候需要在程序中实现,找了好久,发现一篇文章写的挺不错的 http://blog.csdn.net/smartsmile2012/article/details/ ...

  5. iOS 技能集结号

    1. 获取磁盘总空间大小 2. 获取磁盘可用空间大小 3. 获取指定路径下某个文件的大小 4. 获取文件夹下所有文件的大小 5. 获取字符串(或汉字)首字母 6. 将字符串数组按照元素首字母顺序进行排 ...

  6. UVa 11082 Matrix Decompressing(最大流)

    不想吐槽了..sample input 和sample output 完全对不上...调了一个晚上...不想说什么了... -------------------------------------- ...

  7. HTML+CSS笔记 CSS中级 缩写入门

    盒子模型代码简写 回忆盒模型时外边距(margin).内边距(padding)和边框(border)设置上下左右四个方向的边距是按照顺时针方向设置的:上右下左. 语法: margin:10px 15p ...

  8. Linux中fork()函数详解(转)

    一.fork入门知识 一个进程,包括代码.数据和分配给进程的资源.fork()函数通过系统调用创建一个与原来进程几乎完全相同的进程,也就是两个进程可以做完全相同的事,但如果初始参数或者传入的变量不同, ...

  9. Spring Boot Memory Performance

    The Performance Zone is brought to you in partnership with New Relic. Quickly learn how to use Docke ...

  10. [置顶] JDK-Future 模式和实现

    最近的项目用到了多线程,发现java.util.concurrent.Future蛮好用的. 像平时,写多线程一般使用Thread/Runnable,直接扔给线程池执行就好了.但是遇到了一些需要获取线 ...