学习 jsonp
1.起因
js脚本做ajax异步调用的时候,直接请求普通文件存在跨域无权限访问的问题,不管你是静态页面、动态网页、web服务,只要是跨域请求,都无法成功;
如果上句话没明白,我们直接看例子。有两个一模一样的项目,一个webApp01,一个webApp02,分别在两个tomcat里启动,一个端口是8080,一个端口是9080。即两个访问地址是
http://localhost:8080/webApp01/
http://localhost:9080/webApp02/
项目结构也很简单。

webApp01中的index.jsp的代码如下:
<html>
<script type="text/javascript" src="http://localhost:8080/webApp01/jquery-1.11.1.js"></script>
<body>
<script type="text/javascript">
$(function (){
$("#getOtherDomainThings").click(function () { $.get("http://localhost:8080/webApp01/jquery-1.11.1.js", function (data) { alert(data);
})
})
})
</script>
<h2>Hello World!</h2>
<input type="button" value="submit" id="getOtherDomainThings"/>
</body>
</html>
当我们访问http://localhost:8080/webApp01/并单击submit按钮后,看到jquery的脚本成功获取到了,如下图

但当我们改一下代码,要异步获取的文件不在同一个域下会发生什么?index.jsp代码改成如下所示
<html>
<script type="text/javascript" src="http://localhost:8080/webApp01/jquery-1.11.1.js"></script>
<body>
<script type="text/javascript">
$(function (){
$("#getOtherDomainThings").click(function () {
$.get("http://localhost:9080/webApp02/jquery-1.11.1.js", function (data) { alert(data);
})
})
})
</script>
<h2>Hello World!</h2>
<input type="button" value="subbmit" id="getOtherDomainThings"/>
</body>
</html>
我们刷新一下http://localhost:8080/webApp01/并单击submit按钮后,看到jquery的脚本获取失败,如下图

看出来了吧,这就是js脚本做ajax异步调用的时候,直接请求普通文件存在跨域无权限访问的问题。请求压根就没有发出去。
2.解决方式
最简单的方式当然是让异步请求的数据在同一个域下了。不过伟大的攻城师找到了其他方式--jsonp。
jsonp的原理很简单,虽然ajax无法跨域请求,但是所有有src标签的元素都能跨域请求,比 img、iframe、script等。
2.1.JSONP和JSON关系
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。这个地方(json.org)可以学习json。
JSONP是JSON with Padding的略称。它是一个非官方的协议,它允许在服务器端集成Script tags返回至客户端,通过javascript callback的形式实现跨域访问(这仅仅是JSONP简单的实现形式)。
2.2.实现-无格式json
我们继续改造我们的index.jsp的代码
<html>
<script type="text/javascript" src="http://localhost:8080/webApp01/jquery-1.11.1.js"></script>
<body>
<script type="text/javascript">
$(function (){
$("#getOtherDomainThings").click(function () {
$.getJSON("http://localhost:9080/webApp02/jquery-1.11.1.js?callback=?", function (data) { alert(data);
})
})
})
</script>
<h2>Hello World!</h2>
<input type="button" value="subbmit" id="getOtherDomainThings"/>
</body>
</html>
我们刷新http://localhost:8080/webApp01/并单击submit按钮后,看到jquery的脚本成功获取到了,如下图

等等,好像有些不对劲,alert提示窗口没弹出来,而且请求的文件地址全称是http://localhost:9080/webApp02/jquery-1.11.1.js?callback=jQuery1111049328906112350523_1410439234844&_=1410439234845 。
我们在一个新浏览器窗口打开这个链接是没有问题的(当然也不会有什么问题,这已经不涉及到跨域的问题了)。
原来这种跨域请求只能返回json格式的数据,假设我们把这个webApp2上的jquery-1.11.1.js文件内容改成这个样子
{"name":"qyf404","age":123}
我们再次刷新浏览器访http://localhost:8080/webApp01/并单击submit按钮后,看到jquery的脚本成功获取到了,如下图

结果和之前的没有区别,怎么回事?查了下资料,原来jsonp返回的json文本是有格式要求的。
2.3.实现-有格式json
我们在webApp02项目中创建一个test.jsp,内容如下
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
String callback = request.getParameter("callback");
out.print(callback+"({ name:'qyf404',age:'27'});");
%>
我们把webApp01的index.jsp的代码改造一下,如下
<html>
<script type="text/javascript" src="http://localhost:8080/webApp01/jquery-1.11.1.js"></script>
<body>
<script type="text/javascript">
$(function (){
$("#getOtherDomainThings").click(function () {
$.getJSON("http://localhost:9080/webApp02/test.jsp?callback=?", function (data) { alert("name=" + data.name + ",age=" + data.age);
});
});
})
</script>
<h2>Hello World!</h2>
<input type="button" value="subbmit" id="getOtherDomainThings"/>
</body>
</html>
我们再次刷新浏览器访http://localhost:8080/webApp01/并单击submit按钮后,看到jquery的脚本成功获取到了,而且json的内容也传过来了,如下图

大功告成。等等,还有一个问题?异步请求多数会带参数,有参数怎么处理?
2.4实现-有参数有格式json
让我们继续改造webApp01的index.jsp,追加请求参数,代码如下
<html>
<script type="text/javascript" src="http://localhost:8080/webApp01/jquery-1.11.1.js"></script>
<body>
<script type="text/javascript">
$(function (){
$("#getOtherDomainThings").click(function () {
$.getJSON("http://localhost:9080/webApp02/test.jsp?user=qyf404&callback=?", function (data) {
alert("name=" + data.name + ",age=" + data.age);
});
});
})
</script>
<h2>Hello World!</h2>
<input type="button" value="subbmit" id="getOtherDomainThings"/>
</body>
</html>
继续改造webApp02的test.jsp页面,代码如下
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<% String name = request.getParameter("user");
String callback = request.getParameter("callback");
out.print(callback+"({ name:'"+name+"',age:'27'});"); %>
我们再次刷新浏览器访http://localhost:8080/webApp01/并单击submit按钮后,看到jquery的脚本成功获取到了,而且json的内容也传过来了,如下图

没问题,好用的不得了。
最后让我们看看test.jsp到底返回了一个什么神奇的东东
jQuery111102533256879542023_1410490196678({ name:'qyf404',age:'27'});
原来test.jsp是返回了一个可以在本地执行的js脚本。不过这个方法名jQuery111102533256879542023_1410490196678是jQuwey自动生成的。
示例代码下载
学习 jsonp的更多相关文章
- 学习JSONP
最近自己研究 跨域调用js,然后 发现 有jsonp 这种技术,在Jquery中可以使用,于是 研究下原理 发现: 其实 就是 利用<script>的跨域访问的能力. 调用 服务端 返回的 ...
- Django学习---jsonp跨域请求
jsonp跨域请求 我们通过ajax进行跨域请求的时候,请求发送过去,但是在接受返回数据的时候浏览器会进行拦截. 这是由于浏览器存在同源策略机制,同源策略阻止从一个源加载的文档或脚本获取或设置另一个源 ...
- Python学习---JSONP学习180130
同源策略机制 同源:协议://IP:端口[协议,域名,端口相同] 跨域:知道对方接口,同时对方返回的数据也必须是Jsonp格式的 问题描述:Ajax跨域请求数据的时候,实际浏览器已 ...
- Python 系统学习梳理_【All】
Python学习 1. Python学习---Python安装与基础1205 2. Python学习---PyCharm的使用学习 3. Python学习---Python数据类型1206 4. Py ...
- Json格式转化为string格式
今天在学习Jsonp的时候,想通过服务端返回一段json数据,因为使用的服务端是NodeJs,那么就需要在js文件中实现返回json.(这里不懂的同学,可以先了解一下NodeJs的基础概念,在这里,我 ...
- 细说Ajax跨域
一.什么是跨域 跨域问题来自于浏览器同源策略的限制,包括DOM同源限制和Ajax同源限制,本文探讨的是Ajax跨域.Ajax跨域指的是一个页面的Ajax只能请求和当前页面同源的数据,如果发现请求到的数 ...
- 由浅入深学习ajax跨域(JSONP)问题
什么是跨域?说直白点就是获取别人网站上的内容.但这么说貌似又有点混淆,因为通常我们用ajax+php就可以获取别人网站的内容,来看下面这个例子. 来看看跨域的例子,jquery+ajax是不能跨域请求 ...
- 从 AJAX 到 JSONP的基础学习
目录索引: 一.AJAX的概念二.POST && GET三.原生实现AJAX简单示例 3.1 实现代码 3.2 重点说明四.框架隐藏域 4.1 基本概念 4.2 后台写入脚本 4.3 ...
- 关于sencha touch 的JSONP跨域请求的学习研究
此篇文章是对自己在研究学习sencha touch的过程中的点滴记录,主要是JSONP的跨域请求这方面,对于何为是跨域概念还有不熟悉的,可以自己问下度娘. 先上张图: 我要完成的功能就是表格下拉刷新, ...
随机推荐
- java继承的对象中构造函数的调用顺序
建立两个继承关系的对象 public class Machine { public String machieNameString; public Machine() { System.out.pri ...
- Rebalance Customer Balances Utility的使用
用户不管是打开A/R Posted Transactions Detail还是A/R Posted Transactions Summary 窗口,均显示如下一个警示: 打开Currency Code ...
- 关于EF的 序列化类型为“XXX”的对象时检测到循环引用。
在用Ef的时候,也许经常会遇到循环引用的错误. 下面提供解决办法.(不是Json.Net,如果是Json.Net可以给导航属性通过增加特性标签来解决该问题) ef大多数问题,可以通过ToList()来 ...
- 基于类型系统的面向对象编程语言Go
(整理自网络) 面向对象编程 Go语言的面向对象编程(OOP)非常简洁而优雅.说它简洁,在于它没有了OOP中很多概念,比如:继承.虚函数.构造函数和析构函数.隐藏的this指针等等.说它优雅,是它的面 ...
- 值栈(Structs2)
1. 关于值栈: 1). 登陆 时, ${userName} 读取 userName 值, 实际上该属性并不在 request 等域对象中, 而是从值栈中获取的. 2). ValueStack: I. ...
- Greenplum(GP)常见问题,注意事项
1.在安装过程中,出现的 source /usr/local/greenplum-db/greenplum_path.sh 不要写到profile或者./bashrc文件中 因为该句会导致python ...
- Linux下如何查看哪个进程占用内存多?
1.top top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于Windows的任务管理器 可以直接使用top命令后,查看%MEM的内容.可以选择按进程查看或者 ...
- 《深入.NET平台和C#编程》内部测试题
一 选择题 1) 以下关于序列化和反序列化的描述错误的是( C). a) 序列化是将对象的状态存储到特定存储介质中的过程 b) 二进制格式化器的Serialize()和D ...
- SPRING SECURITY 拦截静态资源
情景: <security:intercept-url pattern="/**" access="USER"/> 当在spring securti ...
- [js开源组件开发]localStorage-cache本地存储的缓存管理
localStorage-cache本地存储的缓存管理 距离上次的组件开发有近三个月的时间了,最近一直在做一些杂事,无法静下心来写写代码,也是在学习emberjs,在emberjs中有一个很重要的东西 ...
