以前对于跨域问题,仅仅是知道通过创建script解决,根本没有深入的了解。经过几次的面试,个人觉得有必要去弄清楚jsonp跨域的原理和使用。下面与大家分析我的学习所得。(参考http://www.nowamagic.net/librarys/veda/detail/224)
javascript作为web开发中的前端动态脚本语言,其存在着一个很重要的安全限制,被称为“Same-Origin Policy”(同源策略)。这一策略对于JavaScript代码能够访问的页面内容做了很重要的限制,即JavaScript只能访问与包含它的文档在同一域下的内容。
JavaScript这个安全策略在进行多iframe或多窗口编程、以及Ajax编程时显得尤为重要。根据这个策略,在baidu.com下的页面中包含的JavaScript代码,不能访问在google.com域名下的页面内容;甚至不同的子域名之间的页面也不能通过JavaScript代码互相访问。对于Ajax的影响在于,通过XMLHttpRequest实现的Ajax请求,不能向不同的域提交请求,例如,在abc.example.com下的页面,不能向def.example.com提交Ajax请求,等等。
jsonp跨域原理:大家都知道javascript存在同源限制,script的src属性不受同源限制的影响,所以通过创建script节点可以实现跨域。然而这比不是核心所在,其核心是在于callback回调函数。其主要原理是在客户端先注册一个callback的回调函数,然后通过get方式传给服务器端;然后在服务器端获取callback的值,然后以javascript方式生成一个function,函数名称为callback的值;在将要输出的json数据以参数的方式放置到function中,生成一段javascript语法文档,再返回到客户端;最后客户端浏览器,解析script标签,并执行返回的 javascript 文档,此时数据作为参数,传入到了客户端预先定义好的 callback 函数里。
实例代码:
javascript代码
<script type="text/javascript">
function callbackJson(jsonData){
//对json数据的操作
alert("name"+jsonData.name+"age"+jsonData.age);
}
var url="http://localhost/jsonpTest/JsonpServlet?callback=callbackJson";
var script=document.creatElement(‘script‘);
script.setAttribute(‘src‘,url);
document.getElementsByTagName(‘head‘)[0].appendChild(script);
</script>
服务器代码:
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setCharacterEncoding("utf-8"); String callback=request.getParameter("callback"); //测试用的json数据 Map<String,String> map=new HashMap<String, String>(); map.put("id", "id1"); map.put("name", "name1"); map.put("age", "18"); JSONObject jsonObject = JSONObject.fromObject(map); String returnstr=callback+"("+jsonObject.toString()+")"; PrintWriter out = response.getWriter(); out.println(returnstr); }