加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

简单实现一个JSONP协议的小例子

发布时间:2020-12-16 18:53:09 所属栏目:百科 来源:网络整理
导读:以下内容参考于文章(http://www.cnblogs.com/dowinning/archive/2012/04/19/json-jsonp-jquery.html)实现的小例子,经过这篇文章和自己实现的例子,对jsonp有了更深层的理解,感谢 言归正传,以下是实现过程 jsonp原理个人总结(比较片面)为:在A服务器上

以下内容参考于文章(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),"rn");
		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上绑定的自定义事件ondataavailable
			aLink.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,"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!!!

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读