学习 jsonp 解决跨域

转载自http://www.cnblogs.com/qyf404/p/3868611.html

1.起因

js脚本做ajax异步调用的时候,直接请求普通文件存在跨域无权限访问的问题,不管你是静态页面、动态网页、web服务,只要是跨域请求,都无法成功;

如果上句话没明白,我们直接看例子。有两个一模一样的项目,一个webApp01,一个webApp02,分别在两个tomcat里启动,一个端口是8080,一个端口是9080。即两个访问地址是

http://localhost:8080/webApp01/
http://localhost:9080/webApp02/

项目结构也很简单。

webApp01中的index.jsp的代码如下:

 1 <html>
 2 <script type="text/javascript" src="http://localhost:8080/webApp01/jquery-1.11.1.js"></script>
 3 <body>
 4 <script type="text/javascript">
 5 $(function (){
 6     $("#getOtherDomainThings").click(function () {
 7
 8         $.get("http://localhost:8080/webApp01/jquery-1.11.1.js", function (data) {
 9
10             alert(data);
11         })
12     })
13 })
14 </script>
15 <h2>Hello World!</h2>
16 <input type="button" value="submit" id="getOtherDomainThings"/>
17 </body>
18 </html>

当我们访问http://localhost:8080/webApp01/并单击submit按钮后,看到jquery的脚本成功获取到了,如下图

但当我们改一下代码,要异步获取的文件不在同一个域下会发生什么?index.jsp代码改成如下所示

 1 <html>
 2 <script type="text/javascript" src="http://localhost:8080/webApp01/jquery-1.11.1.js"></script>
 3 <body>
 4 <script type="text/javascript">
 5 $(function (){
 6     $("#getOtherDomainThings").click(function () {
 7         $.get("http://localhost:9080/webApp02/jquery-1.11.1.js", function (data) {
 8
 9             alert(data);
10         })
11     })
12 })
13 </script>
14 <h2>Hello World!</h2>
15 <input type="button" value="subbmit" id="getOtherDomainThings"/>
16 </body>
17 </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的代码

 1 <html>
 2 <script type="text/javascript" src="http://localhost:8080/webApp01/jquery-1.11.1.js"></script>
 3 <body>
 4 <script type="text/javascript">
 5 $(function (){
 6     $("#getOtherDomainThings").click(function () {
 7         $.getJSON("http://localhost:9080/webApp02/jquery-1.11.1.js?callback=?", function (data) {
 8
 9             alert(data);
10         })
11     })
12 })
13 </script>
14 <h2>Hello World!</h2>
15 <input type="button" value="subbmit" id="getOtherDomainThings"/>
16 </body>
17 </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文件内容改成这个样子

1 {"name":"qyf404","age":123}

我们再次刷新浏览器访http://localhost:8080/webApp01/并单击submit按钮后,看到jquery的脚本成功获取到了,如下图

结果和之前的没有区别,怎么回事?查了下资料,原来jsonp返回的json文本是有格式要求的。

2.3.实现-有格式json

我们在webApp02项目中创建一个test.jsp,内容如下

1 <%@ page language="java" contentType="text/html; charset=UTF-8"
2     pageEncoding="UTF-8"%>
3 <%
4 String callback = request.getParameter("callback");
5 out.print(callback+"({ name:‘qyf404‘,age:‘27‘});");
6 7  %>

我们把webApp01的index.jsp的代码改造一下,如下

 1 <html>
 2 <script type="text/javascript" src="http://localhost:8080/webApp01/jquery-1.11.1.js"></script>
 3 <body>
 4 <script type="text/javascript">
 5 $(function (){
 6     $("#getOtherDomainThings").click(function () {
 7         $.getJSON("http://localhost:9080/webApp02/test.jsp?callback=?", function (data) {
 8
 9             alert("name=" + data.name + ",age=" + data.age);
10         });
11     });
12 })
13 </script>
14 <h2>Hello World!</h2>
15 <input type="button" value="subbmit" id="getOtherDomainThings"/>
16 </body>
17 </html>

我们再次刷新浏览器访http://localhost:8080/webApp01/并单击submit按钮后,看到jquery的脚本成功获取到了,而且json的内容也传过来了,如下图

大功告成。等等,还有一个问题?异步请求多数会带参数,有参数怎么处理?

2.4实现-有参数有格式json

让我们继续改造webApp01的index.jsp,追加请求参数,代码如下

 1 <html>
 2 <script type="text/javascript" src="http://localhost:8080/webApp01/jquery-1.11.1.js"></script>
 3 <body>
 4 <script type="text/javascript">
 5 $(function (){
 6     $("#getOtherDomainThings").click(function () {
 7         $.getJSON("http://localhost:9080/webApp02/test.jsp?user=qyf404&callback=?", function (data) {
 8             alert("name=" + data.name + ",age=" + data.age);
 9         });
10     });
11 })
12 </script>
13 <h2>Hello World!</h2>
14 <input type="button" value="subbmit" id="getOtherDomainThings"/>
15 </body>
16 </html>

继续改造webApp02的test.jsp页面,代码如下

1 <%@ page language="java" contentType="text/html; charset=UTF-8"
2     pageEncoding="UTF-8"%>
3 <%
4
5 String name = request.getParameter("user");
6 String callback = request.getParameter("callback");
7 out.print(callback+"({ name:‘"+name+"‘,age:‘27‘});");
8
9  %>

我们再次刷新浏览器访http://localhost:8080/webApp01/并单击submit按钮后,看到jquery的脚本成功获取到了,而且json的内容也传过来了,如下图

没问题,好用的不得了。

最后让我们看看test.jsp到底返回了一个什么神奇的东东

jQuery111102533256879542023_1410490196678({ name:‘qyf404‘,age:‘27‘});

原来test.jsp是返回了一个可以在本地执行的js脚本。不过这个方法名jQuery111102533256879542023_1410490196678是jQuwey自动生成的。

时间: 2024-10-05 23:50:17

学习 jsonp 解决跨域的相关文章

JSONP解决跨域问题,防止表单重复提交,防止XSS攻击

一.跨域问题:能够正常请求,但是没有办法获取到响应结果 解决方案一:设置请求头,在请求的资源中设置Access-Control-Allow-Origin请求头 //3.设置请求头 response.setHeader("Access-Control-Allow-Origin", "*"); 二.JSONP解决跨域问题 普通的跨域访问问题,浏览器会进行拦截,凡是src属性的都不会拦截 ajax:http://www.a.com:8080/a/AServlet JSON

详解Jquery和AngularJs,Servlet中jsonp解决跨域问题(转)

众所周知,jsonp可以解决跨域问题,下面是我在查阅资料和实际项目使用后的一些总结. Jquery中jsonp的使用 //myUrl = "http://localhost:8090/api/test"; $.ajax({ type:"GET", url:myUrl, dataType:"jsonp", jsonp:"callback", jsonpCallback:"jsonpCallback", suc

非jsonp解决跨域问题

1.服务器端解决跨域问题:配置filter在filter中设置请求头import java.io.IOException; import javax.servlet.Filter;import javax.servlet.FilterChain;import javax.servlet.FilterConfig;import javax.servlet.ServletException;import javax.servlet.ServletRequest;import javax.servle

Django 【第十九篇】JS实现的ajax、同源策略和前端jsonp解决跨域问题

一.回顾jQuery实现的ajax 首先说一下ajax的优缺点 优点: AJAX使用Javascript技术向服务器发送异步请求: AJAX无须刷新整个页面: 因为服务器响应内容不再是整个页面,而是页面中的局部,所以AJAX性能高: jquery 实现的ajax index.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <t

深入理解jsonp解决跨域访问

在我们做的这个项目中充分利用jsonp跨域这一个特性,完成了简单的单点登录功能和权限统一认证控制,实现思路并不复杂同各种实现单点登录的产品相比可以说微不足道,各有各的好处.各有各的优点,选择什么方式实现完全取决于我们自己或者项目经理的开发经验,对各种框架的理解程度往往决定了目前开发项目的整体架构. 这不是一项凭空产生的新东西,仅仅是JS的一个特性而已之前没有被我们提及也没有被我们注意到原来经常使用的js还可以跨域呢,觉的我们对已经学过的东西理解还不是不够深入.有些肤浅,JS绝大多数在浏览器中运行

使用JSONP解决跨域问题-代码示例

前段时间用JSONP解决了跨域问题,现在不用了,把代码思路记下来,今后说不定还用得上. JS代码 //查询公告数据 function recentpost(){ $.getJSON(cmsUrl+"/post/recentpost.json?jsoncallback=?",{count:count,categoryid:categoryid}, function(data){ // }); } JS代码,主要就是使用jquery的getJSON方法. 更多描述,来自jquery 文档.

ajax使用jsonp解决跨域问题

发现这几篇博客写的不错,转载过来看: js跨域及解决方案   http://www.cnblogs.com/oneword/archive/2012/12/03/2799443.html 如何解决ajax跨域问题(转)  http://www.cnblogs.com/sunxucool/p/3433992.html 关于JSONP的原理和JQ中使用JSONP    http://blog.csdn.net/joyhen/article/details/11803867 ajax 跨域获取数据js

深入了解jsonp解决跨域访问

在这个项目中,我们做的充分利用jsonp这是一个特点跨界,完成简单的单点登录认证和权限控制的统一.道,各有各的优点.各有各的优点,选择什么方式实现全然取决于我们自己或者项目经理的开发经验,对各种框架的理解程度往往决定了眼下开发项目的总体架构. 这不是一项凭空产生的新东西.不过JS的一个特性而已之前没有被我们提及也没有被我们注意到原来常常使用的js还能够跨域呢,觉的我们对已经学过的东西理解还不是不够深入.有些肤浅,JS绝大多数在浏览器中执行完毕各种动态效果,开发js的人一開始应该就考虑到了浏览器的

Jsonp 解决跨域问题

话不多说直接贴代码: $.ajax({ async: false, url: 'http://****.****.com/Handler.ashx?vueId=iwNavpicS2', type: "GET", dataType: 'jsonp', jsonp: 'jsoncallback', data: null, timeout: 5000, beforeSend: function () { //jsonp 方式此方法不被触发.原因可能是dataType如果指定为jsonp的话,