使用JsonP跨域获取json数据
JsonP示例
JsonP的主要实现举例:
1 | var category = {OBJ: $("#_JD_ALLSORT"), |
其中,http://localhost:8082/category.json的内容为:
1 | category.getDataService( |
其实是一段js,把json包装在参数里。
跨域请求
为什么不能直接用Ajax
直接使用ajax请求另一个端口上的json数据:
1 | //直接使用ajax请求另一个端口上的json数据 |
会出现以下异常:

No 'Access-Control-Allow-Origin'
什么是跨域
当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域。
协议http->https、端口8081->8082、域名Shirtiny.cn->Github.com,都为跨域。
跨域问题的产生
同源策略(Sameoriginpolicy)是一种约定,它是浏览器最核心也最基本的安全功能。
同源策略会阻止一个域的javascript脚本和另外一个域的内容进行交互。所谓同源(即指在同一个域)就是两个页面具有相同的协议(protocol),主机(host)和端口号(port)
跨域的解决方式
- document.domain
- 跨文档通信 API
- JSONP
- CORS
JsonP流程
JSONP 只支持get请求,不支持post请求。
核心思想:用特定方式请求 JSON 数据,服务器收到请求后,将数据放在一个指定名字的回调函数的参数位置传回来。
数据库查询->构建pojo对象
首先需要把数据库中的数据查询出来,数据库中有时并不是直接保存的json数据,如存储的分类目录表:
1 | CREATE TABLE `tb_item_cat` ( |

为了能让查询到的数据转为json格式,我们需要构建Pojo对象。
需要的Json数据格式:

我们可以看到data是根节点,它有很多[0]、[1]、[2]这样的节点。节点包含属性u、n、i,而其中i又是一个子节点,它又包含了自己的u、n、i属性,其中i最终包含了若干字符串。
pojo类的构建
我们把根节点data单独拿出来,构建出JsonData类,因为一个Json里会有1个存放节点集合的data根节点。
1 | package com.SH.Rest.Pojo; |
每个data的节点以及节点的子节点,都有u、n、i 这3个属性,其中i都为一个集合,所以我们构建DataNode类,用来表示子节点。使用@JsonProperty(“”)注解,用来指定对应属性,转换成json数据对应的key名称。
1 | package com.SH.Rest.Pojo; |
Service递归构建,得到节点pojo对象集合
1 | package com.SH.Rest.Service.serviceImpl; |
Controller把节点集合封装到data根节点对象,然后转换成json字符串
1 | package com.SH.Rest.Controller; |
另一种方式(需要spring版本支持):
1 | ("/AllCategory") |
此时客户端只需要发请求:
1 | http://本机:端口/AllCategory?callBack=自定义函数 |
然后会自动调用自定义的函数,并将参数值(也就是json数据)传过来,详情可以看文章开头。