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的更多相关文章

  1. 学习JSONP

    最近自己研究 跨域调用js,然后 发现 有jsonp 这种技术,在Jquery中可以使用,于是 研究下原理 发现: 其实 就是 利用<script>的跨域访问的能力. 调用 服务端 返回的 ...

  2. Django学习---jsonp跨域请求

    jsonp跨域请求 我们通过ajax进行跨域请求的时候,请求发送过去,但是在接受返回数据的时候浏览器会进行拦截. 这是由于浏览器存在同源策略机制,同源策略阻止从一个源加载的文档或脚本获取或设置另一个源 ...

  3. Python学习---JSONP学习180130

    同源策略机制      同源:协议://IP:端口[协议,域名,端口相同]      跨域:知道对方接口,同时对方返回的数据也必须是Jsonp格式的 问题描述:Ajax跨域请求数据的时候,实际浏览器已 ...

  4. Python 系统学习梳理_【All】

    Python学习 1. Python学习---Python安装与基础1205 2. Python学习---PyCharm的使用学习 3. Python学习---Python数据类型1206 4. Py ...

  5. Json格式转化为string格式

    今天在学习Jsonp的时候,想通过服务端返回一段json数据,因为使用的服务端是NodeJs,那么就需要在js文件中实现返回json.(这里不懂的同学,可以先了解一下NodeJs的基础概念,在这里,我 ...

  6. 细说Ajax跨域

    一.什么是跨域 跨域问题来自于浏览器同源策略的限制,包括DOM同源限制和Ajax同源限制,本文探讨的是Ajax跨域.Ajax跨域指的是一个页面的Ajax只能请求和当前页面同源的数据,如果发现请求到的数 ...

  7. 由浅入深学习ajax跨域(JSONP)问题

    什么是跨域?说直白点就是获取别人网站上的内容.但这么说貌似又有点混淆,因为通常我们用ajax+php就可以获取别人网站的内容,来看下面这个例子. 来看看跨域的例子,jquery+ajax是不能跨域请求 ...

  8. 从 AJAX 到 JSONP的基础学习

    目录索引: 一.AJAX的概念二.POST && GET三.原生实现AJAX简单示例 3.1 实现代码 3.2 重点说明四.框架隐藏域 4.1 基本概念 4.2 后台写入脚本 4.3 ...

  9. 关于sencha touch 的JSONP跨域请求的学习研究

    此篇文章是对自己在研究学习sencha touch的过程中的点滴记录,主要是JSONP的跨域请求这方面,对于何为是跨域概念还有不熟悉的,可以自己问下度娘. 先上张图: 我要完成的功能就是表格下拉刷新, ...

随机推荐

  1. 十条jQuery代码片段助力Web开发效率提升

    JQuery是继prototype之后又一个优秀的Javascript库.它是轻量级的js库 ,它兼容CSS3,还兼容各种浏览器(IE 6.0+, FF 1.5+, Safari 2.0+, Oper ...

  2. .net又一个生成缩略图的方法,不变形

    生成缩略图是一个十分常用功能,找到了一个方法,重写部分代码,实用又好用,.net又一个生成缩略图的方法,不变形 /// <summary> /// 为图片生成缩略图 by 何问起 /// ...

  3. 用js解析经json序列化后的C#的DateTime类型数据

    格式化日期(网上到处是),把下面的代码添加到jQuery.js文件中 //格式化日期 Date.prototype.format = function(format) { /* * eg:format ...

  4. jQuery+CSS3实现404背景动画特效

    效果:http://hovertree.com/texiao/jquery/74/ 源码下载:http://hovertree.com/h/bjaf/ko0gcgw5.htm 效果图如下: 代码如下: ...

  5. matlab 调用dos命令和文件操作

    第一.利用!直接调用,简单方便,可以带操作对象:!del A.bat 第二.调用system函数或者dos函数,既可以实现功能,又返回参数,能检查执行情况,方便后面程序的开发,推荐这个 [status ...

  6. Document

    每个载入浏览器的 HTML 文档都会成为 Document 对象.Document 对象使我们可以从脚本中对 HTML 页面中的所有元素进行访问.提示:Document 对象是 Window 对象的一 ...

  7. SSH实例(7)

    运行结果. 浏览课程: 添加课程: 还有删除课程,这里就不演示了.

  8. java 四舍五入保留小数

    // 方式一: double f = 3.1516; BigDecimal b = new BigDecimal(f); double f1 = b.setScale(2, BigDecimal.RO ...

  9. 泛函编程(38)-泛函Stream IO:IO Process in action

    在前面的几节讨论里我们终于得出了一个概括又通用的IO Process类型Process[F[_],O].这个类型同时可以代表数据源(Source)和数据终端(Sink).在这节讨论里我们将针对Proc ...

  10. 简单的mysql查询

    mysql是基于客户机-服务器的数据库.客户机-服务器应用分为两个不同的部分.服务器部分是负责所有数据访问和处理的一个软件. 连接mysql 要连接mysql需要知道如下 主机名: 本地为localh ...