事件背景:

某个站点分为静态产品介绍页面(或由于某原因需要静态化),和一个独立的在线应用程序。静态产品页面属于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. 使用java API查询java类

    一.java API的下载地址 前面列举了常用的java类,但只是介绍了功能,具体详细的用法(比如要知道该类的属性和方法)要需要调用java的API(Application Program Inter ...

  2. Win7搭建Django开发环境

    1.官网下载并安装python 2.7.5 2.配置python 环境变量 在Path中加入python安装目录: PATH=PATH;c:\python26 在PATHEXT中加入以下变量,可以直接 ...

  3. svn中的Trunk,branches,tags深度理解

    trunk.就是主干,这个目录以下直接放源代码了,我们创建项目的时候,把项目源代码放到这个目录.import进svn branches.就是分支,以下可能有非常多trunk,比方trunk_1_0_1 ...

  4. 【原创】ASP.NET Web开发,实现打印Log日志,步骤详解

    添加Log需要四步: 一.引用log4net.dll,详见附件:http://pan.baidu.com/s/1c0hab2g 二.项目根目录下,添加 log4net.xml <?xml ver ...

  5. PHPExcel 导出

    <?php include '../init.inc.php'; include "../db.inc.php"; /* @func 引入类 */ include ROOT. ...

  6. Android 开发笔记“context和getApplicationContext”

    在android中常常会遇到与context有关的内容 浅论一下context : 在语句 AlertDialog.Builder builder = new AlertDialog.Builder( ...

  7. jenkins上集成fitnesse

    烂笔头胜过好记性,恩,养成随手记的习惯 Fitnesse是完全有Java开发的测试框架,跨平台并且便于与其他测试框架和工具的合并(Jenkins.TestNG,Junit以及Selenium的集成) ...

  8. 0520 python

    配置python环境变量我的电脑->右键->属性->高级系统设置->环境变量->(1)用户变量->新建 Path=C:\Python27(2)系统变量->编辑 ...

  9. Python BeautifulSoup中文乱码问题的2种解决方法

    解决方法一: 使用python的BeautifulSoup来抓取网页然后输出网页标题,但是输出的总是乱码,找了好久找到解决办法,下面分享给大家首先是代码 from bs4 import Beautif ...

  10. 查看LINUX系统版本和硬件信息

    查看发行版本 # cat /etc/issue Red Hat Enterprise Linux Server release 6.2 (Santiago) 查看内核 # uname -a Linux ...