加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

ajax 跨域请求问题

发布时间:2020-12-16 00:46:08 所属栏目:百科 来源:网络整理
导读:JQuery1.2后getJSON方法支持跨域读取json数据,原理是利用一个叫做jsonp的概念。当然,究其本质还是通过script标签动态加载js,似乎这是实现真正跨域的唯一方法。 getJSON的用法JQuery手册已经写得很详细,参考手册就可以了,很简单。需要指出的一点是getJSO

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

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

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

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

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

的中,由于安全的问题,浏览器默认是不支持跨域调用的。传统的方法,包括:(参考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官方的例子,客户端掉用如下:

1 $.getJSON(" http://api.flickr.com/services/feeds/photos_public.gne?tags=cat&tagmode=any&format=json&jsoncallback=? ",
2 function(data){
3 $.each(data.items,(i,item){
4
$("<img/>").attr("src""#images");
5 if( i == 3 )returnfalse;
6 });
7 });

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

...

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

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

Jquery取得的可能如下:

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

总结,用JSONP要做两件事:

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

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

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

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

代码:
test.html,例如位于www.qq.com

01 <!DOCTYPE html PUBLIC "-//W3C//DTD 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
02 <htmlxmlns="http://www.w3.org/1999/xhtml">
03 head>
04 metahttp-equiv"Content-Type"content"text/html; charset=gb2312"/>
05 title>jQuery-跨域请求</06 scripttype"text/javascript"src"/js/jquery.js"></script07 </08 "text/javascript"09 jQuery(document).ready(function(){
10 $.ajax({
11 type : "GET",monospace!important; border:0px!important; outline:0px!important; text-align:right!important; float:none!important; vertical-align:baseline!important; position:static!important; left:auto!important; top:auto!important; right:auto!important; bottom:auto!important; height:auto!important; width:2.7em!important; line-height:1.1em!important; font-size:10pt!important; min-height:inherit!important; display:block!important">12 url : "http://www.b.com/server.php&action=getmsg&callback=?",
13 dataType : "jsonp",monospace!important; border:0px!important; outline:0px!important; text-align:right!important; float:none!important; vertical-align:baseline!important; position:static!important; left:auto!important; top:auto!important; right:auto!important; bottom:auto!important; height:auto!important; width:2.7em!important; line-height:1.1em!important; font-size:10pt!important; min-height:inherit!important; display:block!important">14 jsonp: 'callback',monospace!important; border:0px!important; outline:0px!important; text-align:right!important; float:none!important; vertical-align:baseline!important; position:static!important; left:auto!important; top:auto!important; right:auto!important; bottom:auto!important; height:auto!important; width:2.7em!important; line-height:1.1em!important; font-size:10pt!important; min-height:inherit!important; display:block!important">15 success : function(json){
16 $('#msg_box').html(json.msg);
17 return true;
18 }
19 });
20 21 22 body23 divid"msg_box"div24 25 html>

server.php,例如位于 www.baidu.com
<?php
$action=$_GET['action'];
$callback[callback ];
()
{
echo"{$callback}({"msg":"this is a jquery jsonp test message!"})"exit();
}
else
{
error action!;
();
?>

  今天上午,路路同学问了一个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

"http://code.jquery.com/jquery-latest.js"function do_jsonp() {
$.getJSON("http://active.zol.com.cn/guofeng/profile2.php?callback=?",monospace!important; border:0px!important; outline:0px!important; float:none!important; vertical-align:baseline!important; position:static!important; left:auto!important; top:auto!important; right:auto!important; bottom:auto!important; height:auto!important; width:auto!important; line-height:1.1em!important; font-size:10pt!important; min-height:inherit!important">function(data) {
$('#result').val('My name is: ' + data.nick);
ahref"javascript :do_jsonp();">Click me</a><brtextarea"result"cols"50"rows"3"textarea>

profile2.php

= isset('callback']) ?] :''$json //php数组
$arr=array(
'name'=>'lava''nick''比目鱼''contact'=>(
'MSN''lavaguo#msn.com''email''guo.feng#zol.com.cn''website''http://www.zol.com.cn'
= gb2312ToUtf8();//中文需要转UTF-8
= json_encode(//转成json数组
(!empty)) {
.'('.')';//注意这里的格式,调试时这里费了点时间
echogb2312ToUtf8(&$inputis_array)) {
26 = iconv('GB2312''UTF-8'27 }else28 foreach$inputas$k=>$v) {
29 "$k"]);
30 31 32 return33 34 35 你可能注意到上面的例子中,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 函数里.(动态执行回调函数)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

相关内容
推荐文章
站长推荐
热点阅读