这几天, 工作有一新需求, 要求前端extJs页面通过ajax获取另一个项目中的数据并展示出来, 后来发现如果直接在store中使用普通的方法获取数据后台服务没有响应, 总是报错, 最后发现原来是同源策略在作怪,我们知道,JavaScript或jQuery是在Web前端开发中经常使用的动态脚本技术。在JavaScript中,有一个很重要的安全性限制,被称为“Same- Origin Policy”(同源策略)。这一策略对于JavaScript代码能够访问的页面内容做了很重要的限制,即JavaScript只能访问与包含它的文档或脚本 在同一域名下的内容。不同域名下的脚本不能互相访问,即便是子域也不行。关于同源策略,读者可百度更详细的解释,这里不再赘述。
针对这一现象,采用JSONP跨域GET请求是一个常用的解决方案,下面我们来看一下JSONP跨域是如何实现的,并探讨下JSONP跨域的原理.
我们知道,由于同源策略的限制,XmlHttpRequest只允许请求当前源(域名、协议、端口)的资源。若要跨域请求出于安全性考虑是不行的,但是我们发现,Web页面上调用js文件时则不受是否跨域的影响,而且拥有”src”这个属性的标签都拥有跨域的能力,比如<script>、<img>、<iframe>,这时候,聪明的程序猿就想到了变通的方法,如果要进行跨域请求, 通过使用html的script标记来进行跨域请求,并在响应中返回要执行的script代码,其中可以直接使用JSON传递 javascript对象。即在跨域的服务端生成JSON数据,然后包装成script脚本回传,这样就突破同源策略的限制,解决了跨域访问的问题。
具体实现如下:
前端代码:
$.ajax({
dataType:
"jsonp",
jsonp:
"jsoncallback",
jsonpCallback:
"success_jsonpCallback",
url:
"http://localhost:8082/elasticSearchTest/test.do?jsoncallback=?",
method:
"GET",
success:
function(data){}
});
function success_jsonpCallback(data){
examination.grid.getStore().loadData(data);
}
服务器端代码:
@RequestMapping(value =
"/test.do")
@ResponseBody
public void selectAllDatas(HttpServletRequest request,HttpServletResponse response) {
try {
response.setHeader(
"Access-Control-Allow-Origin",
"*");
String callBackName =(String)request.getAttribute(
"jsoncallback");
callBackName=request.getParameter(
"jsoncallback");
String jsonStr =
"{\"name\":\"张三\",\"age\":28}";
String renderStr = callBackName+
"("+jsonStr+
")";
response.setContentType(
"text/plain;charset=UTF-8");
response.getWriter().write(renderStr);
response.getWriter().flush();
}
catch (Exception e1) {
e1.printStackTrace();
}
}
jsonp的原理:
首先在客户端注册一个callback (如:’jsoncallback’), 然后把callback的名字(如:success_jsonpCallback)传给服务器端对应的处理函数。
服务器先生成需要返回给客户端的 json 数据。然后以 javascript 语法的方式,生成一个function , function 名字就是传递上来的参数(jsoncallback)的值(success_jsonpCallback) 。
最后将 json 数据直接以入参的方式,放置到 function 中,这样就生成了一段 js 语法的文档,返回给客户端。 客户端浏览器,解析script标签,并将服务器端返回的数据,作为参数, 传入到了客户端预先定义好的 callback 函数(如上例中jquery $.ajax()方法封装的的success: function (json))里。
实际上跨域是通过动态增加script来加载数据,无法直接获得数据,所以需要使用回调函数。
本文参考: 本文参考了此文章
转载请注明原文地址: https://ju.6miu.com/read-1309587.html