背景:
AJAX向后台(springmvc)发送请求,报错:已阻止交叉源请求:同源策略不允许读取 http://127.0.0.1:8080/DevInfoWeb/getJsonp 上的远程资源。可
以将资源移动到相同的域名上或者启用 CORS 来解决这个问题。
百度一下,发现是遇到了跨域请求请求问题。搜集资料如下
JSONP解释
在解释JSONP之前,我们需要了解下”同源策略“这个概念,这对理解跨域有帮助。基于安全的原因,浏览器是存在同源策略机制的,同源策略阻止从一个源加载的文档或脚本获取或设置另一个源加载额文档的属性。有点绕,说的简单点就是浏览器限制脚本只能和同协议、同域名、同端口的脚本进行交互。
JSONP就是为了解决这一问题的,JSONP是英文JSON with Padding的缩写,是一个非官方的协议。他允许服务端生成script tags返回值客户端,通过javascript callback的形式来实现站点访问。JSONP是一种script tag的注入,将server返回的response添加到页面是实现特定功能。
简而言之,JSONP本身不是复杂的东西,就是通过scirpt标签对javascript文档的动态解析绕过了浏览器的同源策略。
JSONP原理及实现
接下来,来实际模拟一个跨域请求的解决方案。后端为Spring MVC架构的,前端则通过Ajax进行跨域访问。
1、首先客户端需要注册一个callback(服务端通过该callback(jsonp)可以得到js函数名(jsonpCallback)),然后以JavaScript语
法的方式,生成一个function
2、接下来,将JSON数据直接以入参的方式,放置到function中,这样就生成了一段js语法文档,返回给客户端。
3、最后客户端浏览器动态的解析script标签,并执行返回的JavaScript语法文档片段,此时数据作为参数传入到了预先定义好的
回调函数里(动态执行回调函数)。
这种动态解析js文档和eval函数是类似的。
经过一番努力,解决如下:
SpringMVC端:
@RequestMapping("/get") public void get(HttpServletRequest req,HttpServletResponse res) { res.setContentType("text/plain"); String callbackFunName =req.getParameter("callbackparam");//得到js函数名称 try { res.getWriter().write(callbackFunName + "([ { name:"John"}])"); //返回jsonp数据 } catch (IOException e) { e.printStackTrace(); } } @RequestMapping("/getJsonp") @ResponseBody public JSONPObject getJsonp(String callbackparam){ Company company=new Company(); company.setAddress("广州天河华景软件园"); company.setEmail("123456@qq.com"); company.setName("广州讯动网络可以有限公司"); company .setPhone("12345678912"); return new JSONPObject(callbackparam, company); }
AJAX端:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <script src="http://code.jquery.com/jquery-2.1.3.min.js"></script> <script> $(document).ready(function(){ $("#but1").click(function(){ $.ajax({ url:'http://127.0.0.1:8080/DevInfoWeb/get', type: "get", async: false, dataType: "jsonp", jsonp: "callbackparam", //服务端用于接收callback调用的function名的参数 jsonpCallback: "success_jsonpCallback", //callback的function名称,服务端会把名称和data一起传递回来 success: function(json) { alert(json); }, error: function(){alert('Error');} }); }); $("#but2").click(function(){ $.ajax({ url:'http://127.0.0.1:8080/DevInfoWeb/getJsonp', type: "get", async: false, dataType: "jsonp", jsonp: "callbackparam", //服务端用于接收callback调用的function名的参数 jsonpCallback: "success_jsonpCallback", //callback的function名称,服务端会把名称和data一起传递回来 success: function(json) { alert(json); }, error: function(){alert('Error');} }); }); }); </script> </head> <body> <div id="div1"><h2>使用 jQuery AJAX 来改变文本</h2></div> <button id="but1">按钮1</button> <br/> <button id="but2">按钮2</button> </body> </html>
参考文章: