热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

AJAX跨域请求JSONP获取JSON数据

AsynchronousJavaScriptandXML(Ajax)是驱动新一代Web站点(流行术语为Web2.0站点)的关键技术。Ajax允许在不干扰

Asynchronous Javascript and XML (Ajax) 是驱动新一代 Web 站点(流行术语为 Web 2.0 站点)的关键技术。Ajax 允许在不干扰 Web 应用程序的显示和行为的情况下在后台进行数据检索。使用XMLHttpRequest 函数获取数据,它是一种 API,允许客户端 Javascript 通过 HTTP 连接到远程服务器。Ajax 也是许多 mashup 的驱动力,它可将来自多个地方的内容集成为单一 Web 应用程序。

 

不过,由于受到浏览器的限制,该方法不允许跨域通信。如果尝试从不同的域请求数据,会出现安全错误。如果能控制数据驻留的远程服务器并且每个请求都前往同一域,就可以避免这些安全错误。但是,如果仅停留在自己的服务器上,Web 应用程序还有什么用处呢?如果需要从多个第三方服务器收集数据时,又该怎么办?

 

理解同源策略限制

同源策略阻止从一个域上加载的脚本获取或操作另一个域上的文档属性。也就是说,受到请求的 URL 的域必须与当前 Web 页面的域相同。这意味着浏览器隔离来自不同源的内容,以防止它们之间的操作。这个浏览器策略很旧,从 Netscape Navigator 2.0 版本开始就存在。

 

克服该限制的一个相对简单的方法是让 Web 页面向它源自的 Web 服务器请求数据,并且让 Web 服务器像代理一样将请求转发给真正的第三方服务器。尽管该技术获得了普遍使用,但它是不可伸缩的。另一种方式是使用框架要素在当前 Web 页面中创建新区域,并且使用GET 请求获取任何第三方资源。不过,获取资源后,框架中的内容会受到同源策略的限制。

 

克服该限制更理想方法是在 Web 页面中插入动态脚本元素,该页面源指向其他域中的服务 URL 并且在自身脚本中获取数据。脚本加载时它开始执行。该方法是可行的,因为同源策略不阻止动态脚本插入,并且将脚本看作是从提供 Web 页面的域上加载的。但如果该脚本尝试从另一个域上加载文档,就不会成功。幸运的是,通过添加 Javascript Object Notation (JSON) 可以改进该技术。

 

1、什么是JSONP?

 

要了解JSONP,不得不提一下JSON,那么什么是JSON?

JSON is a subset of the object literal notation of Javascript. Since JSON is a subset of Javascript, it can be used in the language with no muss or fuss.

JSONP(JSON with Padding)是一个非官方的协议,它允许在服务器端集成Script tags返回至客户端,通过Javascript callback的形式实现跨域访问(这仅仅是JSONP简单的实现形式)。

 

2、JSONP有什么用?

由于同源策略的限制,XmlHttpRequest只允许请求当前源(域名、协议、端口)的资源,为了实现跨域请求,可以通过script标签实现跨域请求,然后在服务端输出JSON数据并执行回调函数,从而解决了跨域的数据请求。

 

3、如何使用JSONP?

下边这一DEMO实际上是JSONP的简单表现形式,在客户端声明回调函数之后,客户端通过script标签向服务器跨域请求数据,然后服务端返回相应的数据并动态执行回调函数。

 

HTML代码 (任一):

 

Html代码  收藏代码
  1. <meta content&#61;"text/html; charset&#61;utf-8" http-equiv&#61;"Content-Type" />  
  2. <script type&#61;"text/Javascript">  
  3.     function jsonpCallback(result) {  
  4.         //alert(result);  
  5.         for(var i in result) {  
  6.             alert(i&#43;":"&#43;result[i]);//循环输出a:1,b:2,etc.  
  7.         }  
  8.     }  
  9.     var JSONP&#61;document.createElement("script");  
  10.     JSONP.type&#61;"text/Javascript";  
  11.     JSONP.src&#61;"http://crossdomain.com/services.php?callback&#61;jsonpCallback";  
  12.     document.getElementsByTagName("head")[0].appendChild(JSONP);  
  13. script>  

 

或者

 

Html代码  收藏代码
  1. <meta content&#61;"text/html; charset&#61;utf-8" http-equiv&#61;"Content-Type" />  
  2. <script type&#61;"text/Javascript">  
  3.     function jsonpCallback(result) {  
  4.         alert(result.a);  
  5.         alert(result.b);  
  6.         alert(result.c);  
  7.         for(var i in result) {  
  8.             alert(i&#43;":"&#43;result[i]);//循环输出a:1,b:2,etc.  
  9.         }  
  10.     }  
  11. script>  
  12. <script type&#61;"text/Javascript" src&#61;"http://crossdomain.com/services.php?callback&#61;jsonpCallback">script>  

 

Javascript的链接&#xff0c;必须在function的下面。

 

服务端PHP代码 &#xff08;services.php&#xff09;&#xff1a;

 

Php代码  收藏代码
  1.   
  2. //服务端返回JSON数据  
  3. $arr&#61;array(&#39;a&#39;&#61;>1,&#39;b&#39;&#61;>2,&#39;c&#39;&#61;>3,&#39;d&#39;&#61;>4,&#39;e&#39;&#61;>5);  
  4. $result&#61;json_encode($arr);  
  5. //echo $_GET[&#39;callback&#39;].&#39;("Hello,World!")&#39;;  
  6. //echo $_GET[&#39;callback&#39;]."($result)";  
  7. //动态执行回调函数  
  8. $callback&#61;$_GET[&#39;callback&#39;];  
  9. echo $callback."($result)";  

 

如果将上述JS客户端代码用jQuery的方法来实现&#xff0c;也非常简单。

 

$.getJSON
$.ajax
$.get

 

客户端JS代码在jQuery中的实现方式1&#xff1a;

 

Js代码  收藏代码
  1.   
  2.   

 

客户端JS代码在jQuery中的实现方式2&#xff1a;

 

Js代码  收藏代码
  1.   
  2.   

 

客户端JS代码在jQuery中的实现方式3&#xff1a;

 

Js代码  收藏代码
  1.   
  2.   

 

其中 jsonCallback 是客户端注册的&#xff0c;获取跨域服务器上的json数据后&#xff0c;回调的函数。
http://crossdomain.com/services.php?callback&#61;jsonpCallback
这个 url 是跨域服务器取 json 数据的接口&#xff0c;参数为回调函数的名字&#xff0c;返回的格式为

 

Js代码  收藏代码
  1. jsonpCallback({msg:&#39;this is json data&#39;})  

 

Jsonp原理&#xff1a;
首先在客户端注册一个callback, 然后把callback的名字传给服务器。

此时&#xff0c;服务器先生成 json 数据。
然后以 Javascript 语法的方式&#xff0c;生成一个function , function 名字就是传递上来的参数 jsonp.

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

客户端浏览器&#xff0c;解析script标签&#xff0c;并执行返回的 Javascript 文档&#xff0c;此时数据作为参数&#xff0c;传入到了客户端预先定义好的 callback 函数里.&#xff08;动态执行回调函数&#xff09;

 

使用JSON的优点在于&#xff1a;

  • 比XML轻了很多&#xff0c;没有那么多冗余的东西。
  • JSON也是具有很好的可读性的&#xff0c;但是通常返回的都是压缩过后的。不像XML这样的浏览器可以直接显示&#xff0c;浏览器对于JSON的格式化的显示就需要借助一些插件了。
  • 在Javascript中处理JSON很简单。
  • 其他语言例如PHP对于JSON的支持也不错。

JSON也有一些劣势&#xff1a;

  • JSON在服务端语言的支持不像XML那么广泛&#xff0c;不过JSON.org上提供很多语言的库。
  • 如果你使用eval()来解析的话&#xff0c;会容易出现安全问题。

尽管如此&#xff0c;JSON的优点还是很明显的。他是Ajax数据交互的很理想的数据格式。

 

主要提示&#xff1a;

JSONP 是构建 mashup 的强大技术&#xff0c;但不幸的是&#xff0c;它并不是所有跨域通信需求的万灵药。它有一些缺陷&#xff0c;在提交开发资源之前必须认真考虑它们。

 

第一&#xff0c;也是最重要的一点&#xff0c;没有关于 JSONP 调用的错误处理。如果动态脚本插入有效&#xff0c;就执行调用&#xff1b;如果无效&#xff0c;就静默失败。失败是没有任何提示的。例如&#xff0c;不能从服务器捕捉到 404 错误&#xff0c;也不能取消或重新开始请求。不过&#xff0c;等待一段时间还没有响应的话&#xff0c;就不用理它了。&#xff08;未来的 jQuery 版本可能有终止 JSONP 请求的特性&#xff09;。

 

JSONP 的另一个主要缺陷是被不信任的服务使用时会很危险。因为 JSONP 服务返回打包在函数调用中的 JSON 响应&#xff0c;而函数调用是由浏览器执行的&#xff0c;这使宿主 Web 应用程序更容易受到各类攻击。如果打算使用 JSONP 服务&#xff0c;了解它能造成的威胁非常重要。

 

 

关联&#xff1a;

征服 Ajax 应用程序的安全威胁


防止伪造跨站请求

原文地址&#xff1a;

http://justcoding.iteye.com/blog/1366102/


推荐阅读
  • 本文介绍了Java工具类库Hutool,该工具包封装了对文件、流、加密解密、转码、正则、线程、XML等JDK方法的封装,并提供了各种Util工具类。同时,还介绍了Hutool的组件,包括动态代理、布隆过滤、缓存、定时任务等功能。该工具包可以简化Java代码,提高开发效率。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • iOS超签签名服务器搭建及其优劣势
    本文介绍了搭建iOS超签签名服务器的原因和优势,包括不掉签、用户可以直接安装不需要信任、体验好等。同时也提到了超签的劣势,即一个证书只能安装100个,成本较高。文章还详细介绍了超签的实现原理,包括用户请求服务器安装mobileconfig文件、服务器调用苹果接口添加udid等步骤。最后,还提到了生成mobileconfig文件和导出AppleWorldwideDeveloperRelationsCertificationAuthority证书的方法。 ... [详细]
  • SpringMVC接收请求参数的方式总结
    本文总结了在SpringMVC开发中处理控制器参数的各种方式,包括处理使用@RequestParam注解的参数、MultipartFile类型参数和Simple类型参数的RequestParamMethodArgumentResolver,处理@RequestBody注解的参数的RequestResponseBodyMethodProcessor,以及PathVariableMapMethodArgumentResol等子类。 ... [详细]
  • 基于PgpoolII的PostgreSQL集群安装与配置教程
    本文介绍了基于PgpoolII的PostgreSQL集群的安装与配置教程。Pgpool-II是一个位于PostgreSQL服务器和PostgreSQL数据库客户端之间的中间件,提供了连接池、复制、负载均衡、缓存、看门狗、限制链接等功能,可以用于搭建高可用的PostgreSQL集群。文章详细介绍了通过yum安装Pgpool-II的步骤,并提供了相关的官方参考地址。 ... [详细]
  • Spring源码解密之默认标签的解析方式分析
    本文分析了Spring源码解密中默认标签的解析方式。通过对命名空间的判断,区分默认命名空间和自定义命名空间,并采用不同的解析方式。其中,bean标签的解析最为复杂和重要。 ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • 本文介绍了使用AJAX的POST请求实现数据修改功能的方法。通过ajax-post技术,可以实现在输入某个id后,通过ajax技术调用post.jsp修改具有该id记录的姓名的值。文章还提到了AJAX的概念和作用,以及使用async参数和open()方法的注意事项。同时强调了不推荐使用async=false的情况,并解释了JavaScript等待服务器响应的机制。 ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • 在重复造轮子的情况下用ProxyServlet反向代理来减少工作量
    像不少公司内部不同团队都会自己研发自己工具产品,当各个产品逐渐成熟,到达了一定的发展瓶颈,同时每个产品都有着自己的入口,用户 ... [详细]
  • Android开发实现的计时器功能示例
    本文分享了Android开发实现的计时器功能示例,包括效果图、布局和按钮的使用。通过使用Chronometer控件,可以实现计时器功能。该示例适用于Android平台,供开发者参考。 ... [详细]
  • 在Xamarin XAML语言中如何在页面级别构建ControlTemplate控件模板
    本文介绍了在Xamarin XAML语言中如何在页面级别构建ControlTemplate控件模板的方法和步骤,包括将ResourceDictionary添加到页面中以及在ResourceDictionary中实现模板的构建。通过本文的阅读,读者可以了解到在Xamarin XAML语言中构建控件模板的具体操作步骤和语法形式。 ... [详细]
  • 本文介绍了使用cacti监控mssql 2005运行资源情况的操作步骤,包括安装必要的工具和驱动,测试mssql的连接,配置监控脚本等。通过php连接mssql来获取SQL 2005性能计算器的值,实现对mssql的监控。详细的操作步骤和代码请参考附件。 ... [详细]
author-avatar
书友56759136
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有