学习 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的跨域请求这方面,对于何为是跨域概念还有不熟悉的,可以自己问下度娘. 先上张图: 我要完成的功能就是表格下拉刷新, ...
随机推荐
- img[src*="same"]{}
假如你有一组图片,你想选择其中一些名字中带有same的图片,那么你就可以用这种写法,这里的意思就是选择所有正确路径下名字中带有same的图片文件. 譬如说:me_same.png,you_same.p ...
- Visual Studio Code编写HTML
第一步双击打开Visual Studio Code,我们发现什么也没有,但是有一个默认打开的编辑页面.我们先点击File->OpenFoldor 为什么先这么做呢,有两个原因,第一个原因假如你有 ...
- Emit学习(1) - HelloWorld
之前看过Dapper(使用到了Emit), CYQ.Data(另一种思路,没有使用Emit)类的框架之后, 也想自己做一个小框架玩一下, 不过此时能力太过欠缺, 做不了Cyq.Data或者PDF.Ne ...
- 【iOS】Object-C注释
与其他语言一样,Object-C的注释也分为两种,一种是普通注释,一种是文档注释,普通注释通常给阅读代码的人看,而文档注释可以被appledoc识别,在使用的时候xcode能给出智能提示 简单注释 1 ...
- MVC - Action和ActionResult
Action 定义在Controller中的Action方法返回ActionResult对象,ActionResult是对Action执行结果的封装,用于最终对请求进行响应.HTTP是一个单纯的采用请 ...
- 基于吉日嘎底层架构的通用权限管理Web端UI更新:参考DTcms后台界面
经一周的研究学习,看了国内的H+.HUI等,国外的PaperDashboardPro.Make.Metronic BootStrap等,最终选定用一个轻量的,适合中国人的,来自DTcms的后台管理UI ...
- Tigase集群设置
在两台Linux服务器ddd(IP:10.3.93.212)和tsung213(IP:10.3.93.213)上安装了Tigase,要把这两台服务器组成一个Tigase集群,只需要修改这两台服务器的i ...
- 在ListActivity中显示图标
在ListActivity中显示图标,好像并不复杂,实现起来却不轻松. 首先,定义列表中的每一行,这里不是用xml文件定义,而是用一个类定义,CheckBox.ImageView.TextView等控 ...
- 2014 ICPC---Relief grain(树链剖分)
原题链接 Problem Description The soil is cracking up because of the drought and the rabbit kingdom is fa ...
- 泛函编程(27)-泛函编程模式-Monad Transformer
经过了一段时间的学习,我们了解了一系列泛函数据类型.我们知道,在所有编程语言中,数据类型是支持软件编程的基础.同样,泛函数据类型Foldable,Monoid,Functor,Applicative, ...
