【转】JQuery跨域请求 (转http://www.cnblogs.com/myaspnet/archive/2010/12/30/1922335.html)

转载 2011年01月07日 23:18:00

【转】JQuery跨域请求

Posted on 2010-12-30 17:28 itcfj 阅读(11) 评论(0) 编辑 收藏 所属分类: JavaScript

JQuery跨域请求

JQuery1.2后getJSON方法支持跨域读取json数据,原理是利用一个叫做jsonp的概念。当然,究其本质还是通过script标签动态加载js,似乎这是实现真正跨域的唯一方法。

getJSON的用法JQuery手册已经写得很详细,参考手册就可以了,很简单。需要指出的一点是getJSON利用的jsonp需要客户端与服务端作出配合。

  1. 客户端传递的URL里要包含callback变量,以形如callback=?的形式结尾。(jquery会随机生成一个字符串替换?传递给服务端)
  2. 服务端获取客户端传递的callback的值callbackValue,和需要传递的json字符串构成 callbackValue.’(’.json.’)'传回给客户端(示例为php字符串连接方式,其他语言类似)

不出意外的话应该已经可以跨域读取了。

同时输出json数据时候{之前的是(

Ajax应用中,由于安全的问题,浏览器默认是不支持跨域调用的。传统解决的方法,包括:(参考http://bob.pythonmac.org/archives/2005/12/05/remote-json-jsonp/)

Local proxy:
Needs infrastructure (can't run a serverless client) and you get double-taxed on bandwidth and latency (remote - proxy - client).
Flash:
Remote host needs to deploy a crossdomain.xml file, Flash is relatively proprietary and opaque to use, requires learning a one-off moving target programming langage.
Script tag:
Difficult to know when the content is available, no standard methodology, can be considered a "security risk".

以上方法都各有缺陷,都不是很好多解决方案。后来出现了一种叫JSON with Padding的技术,简称JSONP.(原理参考http://bob.pythonmac.org/archives/2005/12/05/remote-json-jsonp/),应 用JSONP可以实现JSON数据的跨域调用。非常的幸运,JQuery1.2以后支持JSONP的应用。下面侧重说明在JQuery中,Json的跨域调用。

      应用JSONP实现Json数据跨域调用,需要服务器端与客户端的合作完成。引用Jquery官方的例子,客户端掉用如下:

$.getJSON("http://api.flickr.com/services/feeds/photos_public.gne?tags=cat&tagmode=any&format=json&jsoncallback=?",

function(data){

$.each(data.items, function(i,item){

$("<img/>").attr("src", item.media.m).appendTo("#images");

if ( i == 3 ) return false;

});

});

    注意这里调用的地址中jsoncallback=?是关键的所在!其中,符号会被Query自动替换成其他的回调方法的名称,具体过程和原理我们这里不理 会。我们关心的是jsoncallback=?起什么作用了?原来jsoncallback=?被替换后,会把方法名称传给服务器。我们在服务器端要做什 么工作呢?服务器要接受参数jsoncallback,然后把jsoncallback的值作为JSON数据方法名称返回,比如服务器是JSP,我们会这 样做:

      ...

      String jsoncallback=request.getParameter("jsoncallback");

      ...

      out.print(jsoncallback+"({/"account/":/"XX/",/"passed/":/"true/",/"error/":/"null/"})");

Jquery取得的数据可能如下:

      JQUET0988788({"account":"XX","passed":"true","error":"null"})

总结,用JSONP要做两件事:

      1/请求地址加参数:jsoncallback=?

      2/服务器段把jsoncallback的值作为方法名传回来,如JQUET098788(...)

jQuery从1.2开始就支持XMLHttp跨域请求了,具体怎么操作?

jQuery中跨域访问的核心原理:JS文件注入,因为因为script标签的src属性是可以跨域的,利用script标签的src属性直接返回非本域名下的数据,具体采用的方式称为:jsonp。

代码:

   test.html,例如位于www.qq.com

     <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

    <html xmlns="http://www.w3.org/1999/xhtml">

    <head>

    <meta http-equiv="Content-Type" content="text/html; charset=gb2312" />

    <title>jQuery-跨域请求</title>

    <script type="text/javascript" src="/js/jquery.js"></script>

    </head>

     <script type="text/javascript">

    jQuery(document).ready(function(){

        $.ajax({

            type : "GET",

            url : "http://www.b.com/server.php&action=getmsg&callback=?",

           dataType : "jsonp",

           jsonp: 'callback',

            success : function(json){

                $('#msg_box').html(json.msg);

                return true;

            }

        });

    });

    </script>

     <body>

    <div id="msg_box"></div>

    </body>

    </html>

   server.php,例如位于www.baidu.com

    <?php

    $action = $_GET['action'];

    $callback = $_GET[callback ];

 

    if ($action)

    {

        echo"{$callback}({"msg":"this is a jquery jsonp test message!"})";

        exit();

    }

    else

    {

        echo"{$callback}({"msg":"error action!"})";

        exit();

    }

    ?>

  今天上午,路路同学问了一个JQuery跨域读取json数据的问题。JQuery用得很少,还真没实际试过。于是上网找个找,看到了JQ的$.getJSON() 方法。先介绍下概念性的东西,网上找的,简单看看就行了。

1.JSONP(JSON with Padding-填充json数据也就是常用的json跨域方式):利用script标签,通过特定的src地址的调用,来执行一个客户端的js函数,在 服务器端生成相对的数据(json格式)并以参数的形式传递给这个客户端的js函数并执行这个函数,前提是需要服务器端的数据输出支持。       

2.为什么使用JSONP:由于 JSON 只是一种含有简单括号结构的纯文本,因此许多通道都可以交换 JSON 消息。因为同源策略的限制,我们不能在与外部服务器进行通信的时候使用 XMLHttpRequest。而JSONP是一种可以绕过同源策略的方法,即通过使用 JSON 与 <script> 标记相结合的方法,从服务端直接返回可执行的JavaScript函数调用或者JavaScript对象。       

3.谁在使用JSONP:dojo、JQuery、Youtube GData API 、Google Social Graph API 、Digg API 、GeoNames webservice、豆瓣API、Del.icio.us JSON API等。

------------------------------------------------------------------------------------------------

  和 AJAX 一样,JSONP 实际上也是早已存在,只是说法相对比较新颖(貌似也出来很久了)。自 1.2 版本起,JQuery加入了对 JSONP 的支持(http://docs.jquery.com/Ajax/jQuery.getJSON#urldatacallback)。我们可以很容易的利用 $.getJSON() 方法(或者其它基于 $.ajax() 的方法),来跨域加载 JSON 数据。我参考官网,写了个JQ测试的例子:

a.html

<html>

<head>

<script src="http://code.jquery.com/jquery-latest.js"></script>

</head>

<body>

<script type="text/javascript">

function do_jsonp() {

    $.getJSON("http://active.zol.com.cn/guofeng/profile2.php?callback=?",

    function(data) {

        $('#result').val('My name is: ' + data.nick);

    });

}

</script>

<a href="javascript :do_jsonp();">Click me</a><br />

<textarea id="result" cols="50" rows="3"></textarea>

</body>

</html>

profile2.php

<?php

$callback = isset($_GET['callback']) ? $_GET['callback'] : '';

$json = '';

//php数组

$arr = array(

     'name' => 'lava',

     'nick' => '比目鱼',

     'contact' => array(

     'MSN' => 'lavaguo#msn.com',

         'email' => 'guo.feng#zol.com.cn',

         'website' => 'http://www.zol.com.cn',

     )

);

$arr = gb2312ToUtf8($arr);//中文需要转UTF-8

$json = json_encode($arr);//转成json数组

if (!empty($callback)) {

    $json = $callback . '(' . $json . ')';//注意这里的格式,调试时这里费了点时间

}

echo $json;

function gb2312ToUtf8(&$input)

{

    if (!is_array($input)) {

        $input = iconv('GB2312', 'UTF-8', $input);

    } else {

        foreach ($input as $k=>$v) {

            gb2312ToUtf8(&$input["$k"]);

        }

    }

    return $input;

}

?>

你可能注意到上面的例子中,url 被写成了http://active.zol.com.cn/guofeng/profile2.php?callback=?,需要说明的是,这个问号会被 jQuery 自动替换为回调函数的函数名(如果是一个匿名函数,JQuery 会自动生成一个带时间戳的函数名)。

总结下JSONP原理:

首先在客户端注册一个callback, 然后把callback的名字传给服务器。

此时,服务器先生成 json 数据。

然后以 javascript 语法的方式,生成一个function , function 名字就是传递上来的参数 jsonp.

最后将 json 数据直接以入参的方式,放置到 function 中,这样就生成了一段 js 语法的文档,返回给客户端。

客户端浏览器,解析script标签,并执行返回的 javascript 文档,此时数据作为参数,传入到了客户端预先定义好的 callback 函数里.(动态执行回调函数)

0
0
(请您对文章做出评价)

【转】http://www.cnblogs.com/springyangwc/archive/2011/03/30/2000388.html

====================================================== 注:本文源代码点此下载 =============================...

简单实用的铁道部12306.cn网站自动化登录(转http://www.cnblogs.com/cnshangsha/archive/2012/01/12/12306cnautologin.html)

铁道部网站登录难点分析 必须使用微软IE浏览器  铁道部网站只支持IE在线付款 网站使用Https协议 客户端不允许跨域访问  技术解析 使用微软IE开发者工具栏即...
  • fjfdszj
  • fjfdszj
  • 2012年01月14日 12:50
  • 1832

Android 2.1 源码结构分析(转自http://www.cnblogs.com/kanggezi/archive/2010/11/30/1891855.html)

001Android 2.1 源码结构分析002lee003Android 2.1004|-- Makefile005|-- bionic               (bionic C库)006|-...

Win2003 域控制器设置和客户端安装 (转http://www.cnblogs.com/xpxu/archive/2009/10/12/1582037.html)

win2003 server域控制器安装,设置,及问题处理      首先,当然是在成员服务器上安装上Windows Server 2003,安装成功后进入系统,      我们要做的第一件...
  • fjfdszj
  • fjfdszj
  • 2011年10月11日 20:16
  • 1396

js读取文件(转:http://www.cnblogs.com/huifeidejian/archive/2010/08/09/1795680.html)

cript" type = "text/javascript">             var getActiveXObject ,getFile,someMessage;           ...
  • fjfdszj
  • fjfdszj
  • 2011年09月14日 15:40
  • 726

使用XMLHTTP Request Object获取服务器数据 (转http://www.cnblogs.com/birdshome/archive/2004/12/26/82238.html)

使用XMLHTTP Request Object获取服务器数据     在Web客户端使用xmlhttp对象,可以十分方便的和服务器交换数据,我们可以获取和发送任何类型的数据,甚至二进制数据到服务器上...
  • fjfdszj
  • fjfdszj
  • 2011年04月15日 15:31
  • 378

【原作者:吴秦(Tyler)http://www.cnblogs.com/skynet/archive/2010/04/12/1709892.html】Android开发之旅:环境搭建及HelloWo

Android开发之旅:环境搭建及HelloWorld 2010-04-12 00:45 by 吴秦, 801360 阅读, 138 评论, 收藏, 编辑 ——工欲善其事必先利其器...

JQuery上传插件Uploadify使用详解 http://www.cnblogs.com/oec2003/archive/2010/01/06/1640027.html

Uploadify是JQuery的一个上传插件,实现的效果非常不错,带进度显示。不过官方提供的实例时php版本的,本文将详细介绍Uploadify在Aspnet中的使用,您也可以点击下面的链接进行演示...

jquery ui 1.7 ui.tabs 动态添加与关闭(按钮关闭+双击关闭) 【转载】(http://www.cnblogs.com/lijia7436/archive/2010/03/31/1701193.html)

1$(document).ready(function(){ 2      $('#tabs').tabs({add:addEventHandler});  //给tabs块绑定addEventHan...
  • fjfdszj
  • fjfdszj
  • 2011年04月16日 00:10
  • 1239

关于Jquery中ajax方法data参数用法的总结http://www.cnblogs.com/tim190/archive/2010/10/20/1856523.html

关于Jquery中ajax方法data参数用法的总结 jquery手册描述: data 发送到服务器的数据。将自动转换为请求字符串格式。GET 请求中将附加在 URL 后。查看 proce...
  • zhqzou
  • zhqzou
  • 2012年03月27日 17:48
  • 502
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:【转】JQuery跨域请求 (转http://www.cnblogs.com/myaspnet/archive/2010/12/30/1922335.html)
举报原因:
原因补充:

(最多只允许输入30个字)