IT忍者神龟之jQuery 使用 $.getJSON() 跨域获取 JSON 数据

假设在服务器上有文件 http://test.unmi.cc/json.php 文件,它的内容为:

[代码 1]


01

02

03

04

05

06

07

08

09

10

<?php

header(‘Content-type:
application/json‘
);

$user

=
array

(

    "name" 

=>
"Unmi",

    "blog"

=>
"http://unmi.cc"

);

echo

json_encode(
$user);

?>

要是在同一个域上要取该文件的内容,那好办,比如同为 test.unmi.cc 域上的 ajax.html 文件中写上:

[代码 2]


01

02

03

04

05

06

07

08

09

10

<script
src=
"http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>

<script>

$(function(){

    $.getJSON("json.php",
/*跨域时换成
"http://test.unmi.cc/json.php"*/

        function(data){

            alert(data.name);

        }

    )

});

</script>

那么可以弹出 data.name 为 “Unmi".

但如果 ajax.html 是放在另一个域上,比如说 ajax.html 是在本地,再来取 http://test.unmi.cc/json.php 的 json 数据时,这时候在 Firebug 中你可以看到其实也会用 ajax 来请求 http://test.unmi.cc/json.php 的数据,但是 XHR 里的 Response 是空的,字节数是对的。也就是说对 http://test.unmi.cc/json.php 的 http 请求/响应是完成了的,但基于安全性考虑,浏览器会拒绝处理响应数据。

不少资料上会说,在 jQuery 使用 $.getJSON() 请求数据时,如果判断到请求的数据不在同一个域上会自动采用 JSONP (JSON with Padding) 的方式进行跨域请求,但是还忽略了两点:

一是需求发送 callback=? 或 jsoncallback=? 请求参数

二是这时候还需要服务端的支持,送出的数据就不是 JSON 数据,而是由 callback 或  jsoncallback 参数指定名称的 javascript 函数调用,参数才是 JSON 数据

所以要完成 $.getJSON() 的跨域调用服务端和客户端必须分别改造成:

服务端 http://test.unmi.cc/json.php

[代码 3]


01

02

03

04

05

06

07

08

09

10

<?php

header(‘Content-type:
application/javascript‘
);

$user

=
array

(

    "name" 

=>
"Unmi",

    "blog"

=>
"http://unmi.cc"

);

echo

$_GET
[‘callback‘]."(".json_encode($user).");";

?>

客户端   ajax.html 文件内容:

[代码 4]


01

02

03

04

05

06

07

08

09

10

<script
src=
"http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>

<script>

$(function(){

    $.getJSON("http://test.unmi.cc/json.php?callback=?"

        function(data){

            alert(data.name);

        }

    )

});

</script>

这样就可以得到预期的结果,就是这里多了个 callback,也可以使用 jsoncallback。

我们用 Firebug 来观察上面代码在进行跨域请求时,并未发出 XHR 请求,而是使用了 <script src=""> 去请求的脚本,它发出的请求是:

http://test.unmi.cc/json.php?callback=jQuery172018016521480994097_1338136926617&_=1338136926659

得到的响应数据是:

jQuery172018016521480994097_1338136926617({"name":"Unmi","blog":"http:\/\/unmi.cc"});

上面的 callback=? 参数并不是说发送了参数值为 ?,再说 ? 号也得转义才成,? 号只是个点位符,会由 jQuery 来生成一个方法名,如这里的

jQuery172018016521480994097_1338136926617

如果把 [代码 4] 放在与 http://test.unmi.cc/json.php 的同一个域上去执行,那么它发出的请求与响应会是与跨域时一样的,但它却会以 XHR 方式来请求数据,而不是 <script src=""> 方式。

$.getJSON() 跨域调用的原理,基本上在 jQuery 里涉及到 ajax 跨域的调用都是通过 <script src=""> 来完成的,不知有没有用 <iframe src=""> 的。解释 $.getJSON() 在跨域时,其实就是指定的 $.ajax() 里的 dataType 为 jsonp,进而和 $.getScript 的实现原理是一样的:

[代码 5]


1

2

3

4

var

head = document.getElementsByTagName(
"head")[0];

var

script = document.createElement(
"script");

script.src
= s.url;

head.appendChild(script);

记得在  $.getJSON() 如果是跨域时获得的是一段 JavaScript 调用代码,函数名由  callback 指定,该函数由 jQuery 生成,JSON 数据作为参数传给该 callback 函数,最后这个 JSON 数据也会传递到 success 函数中去,所以我们能够像 $getJSON() 获取本域的 JSON 数据那样使用。

不用便捷的  $.getJSON() 而采用基础的 $.ajax() 函数来作跨域调用就得写成:

[代码 6]


01

02

03

04

05

06

07

08

09

10

11

12

<script
src=
"http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>

<script>

$(function(){

     
$.ajax({

       url:
"http://test.unmi.cc/json.php",

       dataType:‘jsonp‘,

       success:
function(data){

         
alert(data.name);

       }

   });

});

</script>

只告诉它 dataType 为  jsonp 即可,它同样是发出类似

http://test.unmi.cc/json.php?callback=jQuery172018016521480994097_1338136926617&_=1338136926659

的请求,callback 参数名是默认的。

再加上两个 $.ajax 跨域获取 JSON 数据时两个重要的选项,比如下面的代码:

[代码 7]


01

02

03

04

05

06

07

08

09

10

11

12

13

14

<script
src=
"http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>

<script>

$(function(){

     
$.ajax({

       url:
"http://test.unmi.cc/json.php",

       dataType:‘jsonp‘,

       jsonp:‘jsonpcallback‘,

       jsonpCallback:‘jsonCallbackFunction123‘,

       success:
function(data){

         
alert(data.name);

       }

   });

});

</script>

执行后发出的请求是:

http://test.unmi.cc/json.php?jsonpcallback=jsonCallbackFunction123&_=1338139076306

响应是:

jsonCallbackFunction123({"name":"Unmi","blog":"http:\/\/unmi.cc"});

与上面对照一下就能看出来 jsonp 用来指定传送函数名的请求参数名,而不是默认的 callback,jsonpCallback 指定回调函数的名数,而不用默认 jQuery 随机生成的那一长串的函数名称。

而且,因为回调函数名是已知的,所以你可以自己定义那个 jsonCallbackFunction123 函数,原型是:

function jsonCallbackFunction123(data) { ... },

即使自定义了这个回调函数,由  success 指定的函数同样会得到调用,会在 jsonCallbackFunction123 之后被调用。

关于 $.getJSON() 可以看官方的说明 http://api.jquery.com/jQuery.getJSON/,其中有一个取
flickr 上照片的例子。

顺便引入一个可在线测试各种 JavaScript 框架的网站 http://jsfiddle.net/praveen_prasad/tnaWd/,支持各版本的
jQuery, Mootools, Prototype, YUI, Glow, Dojo, Processing, ExtJS, Raphael, RightJS, ThreeJS, Zepto, Enyo, Shipyar, MooFx 和 Knockout。

试用一下,进到 http://jsfiddle.net/praveen_prasad/tnaWd/,选择框架为
jQuery 1.7.2, 事件为 onLoad 或 onDomReady,然后在 Javascript 框中贴入代码:

[代码  8]


1

2

3

4

5

6

7

8

9

//$(function(){  

   
$.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(
"body");

   
        
if

( i == 3 )
return

false
;

   
      
});

    });

//});

再点击上边的 Run 按钮,一会儿就能看到 Result 框中显示四个可爱的猫咪图片。

参考:1. Using JQuery,
AJAX and JSONP to do cross-domain calls with PHP

http://unmi.cc/jquery-getjson-cross-domain/

时间: 2024-12-21 05:43:27

IT忍者神龟之jQuery 使用 $.getJSON() 跨域获取 JSON 数据的相关文章

jquery的ajax和getJson跨域获取json数据

原文:http://www.cnblogs.com/yqskj/archive/2013/06/12/3133247.html 很多开发人员在使用jquery在前端和服务器端进行数据交互,所以很容易会认为在前端利用jquery就可以读取任何站点的数据了.近日在进行开 发时,因为要和第三方公司的一个项目进行数据的共享,因为考虑多不占用服务器的资源,遂决定直接在html进行数据的读取,不走服务器端进行中转了.然后 正好就遇到了浏览器端跨域访问的问题. 跨域的安全限制都是指浏览器端来说的,服务器端不存

【转载1】jquery的ajax和getJson跨域获取json数据

目前浏览器端跨域访问常用的两种方法有两种: 1.通过jQuery的ajax进行跨域,这其实是采用的jsonp的方式来实现的. jsonp是英文json with padding的缩写.它允许在服务器端生成script tags至返回至客户端,也就是动态生成javascript标签,通过javascript callback的形式实现数据读取. html代码: 1 $(function(){ 2 3 $("#ww").click(function(){ 4 5 $.ajax({ 6 ty

jquery跨域请求json数据

//服务端生成json数据json.php <?php $json=array("Volvo","BMW","SAAB"); $cb = $_GET['callback']; echo $cb.'('.json_encode($json, true).')'; ?> //客户端Ajax请求数据<script> $(document).ready(function() { var url="http://域名/js

Asp.net MVC3 实现jquery跨域获取json

JSONP可以帮我们解决跨域访问的问题.JSONP is JSON With Padding. 这里我们将不再解释其原理.我们来看在ASP.NET MVC 3 如何实现.首先我们需要定义一个JsonpResult. 代码像这样, 直接继承自JsonResult, override了ExecuteResult方法 public class JsonpResult : JsonResult { private static readonly string JsonpCallbackName = "c

jquery+thinkphp实现跨域抓取数据的方法

jquery的$.post发送数据到服务器后台,在由后台的PHP代码执行远程抓取,存到数据库ajax返回数据到前台,前台用JS接受数据并显示. //远程抓取获取数据$("#update_ac").click(function() {$username = $("#username").text();$("#AC,#rank,#Submit,#solved,#solved2,#solved3").ajaxStart(function(){$(thi

jquery 跨域获取网页数据

<script language="javascript" src="http://cbsahhs.blog.163.com/jquery.min.js"></script><script language="javascript">function jsonajax() { $.ajax({            type : "GET",            url : "h

jQuery使用ajax跨域获取数据

var webMethod = "http://localhost:54473/Service1.asmx/HelloWorld";  jQuery.support.cors = true; //之前没有加这句老是提示no transport,我没去深想. $.ajax ({ type: "POST", contentType: "application/x-www-form-urlencoded", dataType: "html&q

jquery ajax jsonp跨域调用实例代码

今天研究了AJAX使用JSONP进行跨域调用的方法,发现使用GET方式和POST方式都可以进行跨域调用,这里简单分享下,方便需要的朋友 客户端代码 复制代码 代码如下: <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="WebApp.WebForm1" %><!DOCTYPE html P

jQuery异步请求(如getJSON)跨域解决方案

相信大家在使用jQuery异步请求非自己网站内相对资源(通过别人站点上的URL直接读取)使经常会遇到如下错误吧,实际上这些错误都是浏览器安全机制“搞的鬼”,才让我们开发路上遇到了拦路虎. 当你直接在浏览器中请求:“http://www.weather.com.cn/adat/sk/101110101.html”时会得到你需要的json数据. 当你通过jQuery的getJSON方法读取时你就会得到下列错误. Chrome提示错误: XMLHttpRequest cannot load http: