Jsonp(JSON with Padding) 是 json 的一种"使用模式",可让网页从别的域名(网站)
那获取资料,即跨域读取数据。
为何咱们从不一样的域(网站)访问数据须要一个特殊的技术(JSONP )呢?这是由于同
源策略。javascript
跨域是指一个域(网站)下的文档或脚本试图去请求另外一个域(网站)下的资源。html
同源策略/SOP(Same origin policy)是一种约定,由 Netscape 公司 1995 年引入浏览器,
它是浏览器最核心也最基本的安全功能,如今全部支持 JavaScript 的浏览器都会使用这个策
略。若是缺乏了同源策略,浏览器很容易受到 XSS、CSFR 等攻击。所谓同源是指"协议+域
名+端口"三者相同,即使两个不一样的域名指向同一个 ip 地址,也非同源。java
1.) Cookie、LocalStorage 和 IndexDB 没法读取2.) DOM 和 Js 对象没法得到
3.) AJAX 请求不能发送
4 常见跨域场景node
1) 经过 jsonp 跨域 2) document.domain + iframe 跨域 3) location.hash + iframe 4) window.name + iframe 跨域 5) postMessage 跨域 6) 跨域资源共享(CORS) 7) nginx 代理跨域 8) nodejs 中间件代理跨域 9) WebSocket 协议跨域
JSONP 的优势是:它不像 XMLHttpRequest 对象实现的 Ajax 请求那样受到同源策略的
限制;它的兼容性更好,在更加古老的浏览器中都 能够运行,不须要 XMLHttpRequest 或
ActiveX 的支持;而且在请求完毕后能够经过调用 callback 的方式回传结果。
JSONP 的缺点则是:它只支持 GET 请求而不支持 POST 等其它类型的 HTTP 请求;它只支持跨域 HTTP 请求这种状况,不能解决不一样域的两个页面之间如何进行 JavaScript 调用
的问题。jquery
1 搭建跨域场景
1.1 需求:
1)建立两个 web 工程,名称为 jsonDemo1(8080)、jsonDemo2(9090)
2)jsonDemo1 中提供一个 index.jsp。
3)在 jsonDemo1 的 index.jsp 中经过 Jquery 的 Ajax 跨域请求 jsonDemo2
4)jsonDemo2 中使用 springMVC 处理请求,返回一个 json 对象
5)在 jsonDemo1 中将返回的结果插入到 index.jsp 中
1.2 建立项目
1.2.1 jsonDemo11.2.2 jsonDemo2nginx
2 使用 JsonP 解决跨域
2.1 Ajax 跨域请求时会出现异常web
2.2 在 ajax 中请求方式有所改变ajax
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> <script type="text/javascript" src="/js/jquery-1.7.2.js"></script> <script type="text/javascript"> $(function(){ $("#but").click(function(){ $.ajax({ type:"get", url:"http://localhost:9090/user/findUser", dataType:"jsonp", jsonp:"callback", success:function(data){ alert(data); var str = ""; for(i=0;i<data.length;i++){ str+= data[i].userid+""+data[i].username+" "+data[i].userage+" "; } $("#show").html(str); } }); }); }); </script> </head> <body> <span id="show"></span> <input type="button" value="OK" id="but"/> </body> </html>
2.3 请求的 Controller 须要改变spring
@Controller @RequestMapping("/user") public class UserController { @RequestMapping("/findUser") @ResponseBodypublic String findUser(String callback){ Users user = new Users(1, "admin", 20); Users user1 = new Users(2, "zhangsan", 22); Users user2 = new Users(3, "lisi", 24); List<Users> list = new ArrayList<>(); list.add(user); list.add(user1); list.add(user2); String json = JsonUtils.objectToJson(list); //callback({id:1,name:zhangsan...}) return callback+"("+json+")"; } }
3 SpringMVC 对 JsonP 的支持json
@Controller @RequestMapping("/user") public class UserController { @RequestMapping("/findUser") @ResponseBodypublic Object findUser(String callback){ Users user = new Users(1, "admin", 20); Users user1 = new Users(2, "zhangsan", 22); Users user2 = new Users(3, "lisi", 24); List<Users> list = new ArrayList<>(); list.add(user); list.add(user1); list.add(user2); //json 转换 MappingJacksonValue mv = new MappingJacksonValue(list); mv.setJsonpFunction(callback); return mv; } }
注意:须要依赖 Jackson 的 jar 包