简单实现一个JSONP协议的小例子
来源:互联网 发布:亚马逊kindle windows 编辑:程序博客网 时间:2024/04/30 15:45
以下内容参考于文章(http://www.cnblogs.com/dowinning/archive/2012/04/19/json-jsonp-jquery.html)实现的小例子,经过这篇文章和自己实现的例子,对jsonp有了更深层的理解,感谢
言归正传,以下是实现过程
jsonp原理个人总结(比较片面)为:在A服务器上的页面向B服务器上发送一个url请求,请求里包含一个参数callback(约定),参数值是A服务器上页面里定义的一个函数(函数的参数个数类型等应该也需要约定,例子中我们约定一个string参数),为方便讲解这里我们定义为flightHandler (可以任意),而B服务器接收到请求后给A返回一个js文件,这个文件里的内容为包含一个名称为flightHandler的 方法,而方法的参数就是A服务器真正想从B服务器上的有用信息。A在接受到信息后就可以随意处理啦!这样就实现了跨域访问。
首先,我要编写B服务器上的服务页面(不想掉后台,只想简单在页面用js实现),以下是第一版
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><%@taglib prefix="c" uri="/WEB-INF/c.tld"%><%String callback = request.getParameter("callback");%><!DOCTYPE HTML><html><head><title>JSONP【<%=callback%>】</title></head><body class=""><script type="text/javascript"> var callback = "<%=callback%>";window.onload = function(){downloadFile(callback+"('hello')",callback+".js");} function downloadFile(resultStr,title){resultStr=resultStr.replace(new RegExp(/(<br>)/g),"\r\n");resultStr=resultStr.replace(new RegExp(/<font color=\"red\">/g),"");resultStr=resultStr.replace(new RegExp(/<\/font>/g),"");//alert(resultStr);//文件下载var aLink = document.createElement('a');if(aLink.dispatchEvent){//触发事件方法,高级浏览器(chrome,firefox等) var blob = new Blob([resultStr]); var evt = document.createEvent("HTMLEvents"); evt.initEvent("click", false, false);//initEvent 不加后两个参数在FF下会报错, 感谢 Barret Lee 的反馈 aLink.download = title; aLink.href = URL.createObjectURL(blob); aLink.dispatchEvent(evt);}else{//触发事件方法,ie下fireEvent//调用document对象的createEventObject方法得到一个event的对象实例。var blobi = new Blob([resultStr]);aLink.download = title; aLink.href = URL.createObjectURL(blobi); var event = document.createEventObject();event.eventType = 'message';//触发document上绑定的自定义事件ondataavailableaLink.fireEvent('onclick', event);}}</script></body></html>
成功下载,那接下来就把这个jsp放到另外一个域名下的服务器上,然后在本地用下面代码调用(其他相同代码省略)
var callback = "<%=callback%>";window.onload = function(){doIt();} var flightHandler = function(data){ alert('返回的结果是:' + data + ' 。'+data.name); };function doIt(){ // 得到航班信息查询结果后的回调函数 // 提供jsonp服务的url地址(不管是什么类型的地址,最终生成的返回值都是一段javascript代码) var url = "http://106.xx.xx.xx:8081/xxm/json.jsp?callback=flightHandler"; alert(url); // 创建script标签,设置其属性 var script = document.createElement('script'); script.setAttribute('src', url); // 把script标签加入head,此时调用开始 document.getElementsByTagName('head')[0].appendChild(script); }
但是发现一直不能正确返回所要的js,后来发现这样是不行的,因为这样定义的script脚本标签得到的是整个html页面,学艺不精就容易走岔路,于是寻找jsp页面直接返回文件的方法
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><%@ page language="java" import="java.io.*" %><%@taglib prefix="c" uri="/WEB-INF/c.tld"%><%String path = request.getContextPath();String callback = request.getParameter("callback");String basePath = request.getScheme() + "://"+ request.getServerName() + ":" + request.getServerPort()+ path + "/";String result = callback+"('{name:shywind,age:10001,interest:guess}');";response.setContentType("application/octet-stream");response.setHeader("Content-Disposition", "attachment;filename=test.js");OutputStream ouputStream = response.getOutputStream();ouputStream.write(result.getBytes());ouputStream.flush();ouputStream.close();%>果然成功啦,只是看下tomcat日志发现一直报错,
java.lang.IllegalStateException: getOutputStream() has already been called for this response at org.apache.coyote.tomcat5.CoyoteResponse.getWriter(CoyoteResponse.java:599) at org.apache.coyote.tomcat5.CoyoteResponseFacade.getWriter(CoyoteResponseFacade.java:163)
<span style="white-space:pre"></span>......
百度下找到http://qify.iteye.com/blog/747842,根据他的方法果然解决了,以下是最终结果
String basePath = request.getScheme() + "://"+ request.getServerName() + ":" + request.getServerPort()+ path + "/";String result = callback+"('{name:shywind,age:10001,interest:guess}');";response.setContentType("application/octet-stream");response.setHeader("Content-Disposition", "attachment;filename=test.js");OutputStream ouputStream = response.getOutputStream();ouputStream.write(result.getBytes());ouputStream.flush();out.clear(); out = pageContext.pushBody(); ouputStream.close();/**os=null; response.flushBuffer(); */
OK!!!
0 0
- 简单实现一个JSONP协议的小例子
- 一个简单的jsonp例子
- Laravel实现一个简单的小例子
- 一个简单的AJAX的小例子
- 一个简单的 java socket 小例子
- ExpandableListView用法的一个简单小例子
- 一个简单的epoll小例子
- ExpandableListView用法的一个简单小例子
- 一个简单的AsyncTast小例子
- 一个简单的MVP小例子
- Spring入门-一个简单的小例子
- jsonp跨域请求的小例子
- Linux C编程的一个小例子——实现一个简单的who命令(第一版)
- 自己实现简单shell的小例子
- 实现代理的一个小例子
- EXT实现一个树的小例子
- 一个UDP实现广播的小例子
- unity3d射线的原理用法以及一个利用射线实现简单拾取的小例子
- Dts-link
- 自定义Dialog显示灰色背景, Dialog设置大小
- golang rc4加密算法的使用
- linux 删除带有特殊符号的文件及文件夹
- /*弹性盒子*/
- 简单实现一个JSONP协议的小例子
- 输入框添加Emoje表情demo
- Dts- status
- Openwrt 端口映射的常见问题
- C# 委托(Delegate)
- java类中的静态变量是什么时候初始化的
- TestNG系列-第五章 测试方法、测试类和测试分组(续2)-参数
- mybatis动态sql中的trim标签的使用
- 136. Single Number (Easy)