跨域问题及解决方案(jsonp)

一:什么是跨域?

跨域是指的浏览器跨域,由于同源策略的限制,无法共享不同域名的资源(所谓的同是指域名相同,协议相同,端口相同),不同域名之
间,或同一域名不同端口之间无法互相访问,典型的报错如下:

跨域问题及解决方案(jsonp)

二.实例

该项目前后台系统分离,并且前台系统的门户和服务层是分开的,如下图(多设备可共用服务层),这就意味
着portal(门户)和服务层是两个独立的项目,发布时会使用不同的域名或是同一域名下的不同端口,假设我
们使用同一域名下的8081端口发布服务层项目,使用8082端口发布门户项目

跨域问题及解决方案(jsonp)

URL_Serv: "http://localhost:8081/category.json"

//在门户项目中使用ajax请求json数据,服务端如果直接返回数据给客户端(8081端口---->8082端口)
$.getJSON(this.URL_Serv, function(json){
            category.getDataService(json);
});

js报错:(跨域问题)

跨域问题及解决方案(jsonp)

三.解决方案

jsonp方式简介

JSONP实现跨域请求的原理简单的说,就是动态创建<script>标签,然后利用<script>的src 不受同源策略约束来跨域获取数据。

JSONP 由两部分组成:回调函数和数据。回调函数是当响应到来时应该在页面中调用的函数。回调函数的名字一般是在请求中指定的。而数据就是传入回调函数中的 JSON 数据。

jsonp原理图

跨域问题及解决方案(jsonp)

jsonp实现

(1)前端方案一:动态创建<script>标签,设置其src,回调函数在src中设置:

var script = document.createElement("script");
script.src = "https://api.douban.com/v2/book/search?
q=javascript&count=1&callback=handleResponse";
document.body.insertBefore(script, document.body.firstChild);

<script type="text/javascript">
    function handleResponse(response){
            console.log(response);
    }
</script>

(2)前端方案二:利用getJSON来实现,只要在地址中加上callback=?参数即可

$.getJSON("https://api.douban.com/v2/book/search?q=javascript&count=1&callback=?", 
function(data){
                console.log(data);
            });

controller层

返回的JSON作为参数传入回调函数中
方式一:

@Controller
public class ItemCatController {
    
    @Autowired
    private ItemCatService itemCatService;

    @RequestMapping(value="/itemcat/list", 
            produces=MediaType.APPLICATION_JSON_VALUE + ";charset=utf-8")
    @ResponseBody
    public String getItemCatList(String callback) {
        CatResult catResult = itemCatService.getItemCatList();
        //把pojo转换成字符串
        String json = JsonUtils.objectToJson(catResult);
        //拼装返回值
        String result = callback + "(" + json + ");";
        return result;
    }
}

其中:produces=MediaType.APPLICATION_JSON_VALUE + ";charset=utf-8" 是用来解决乱码
方式二:

@RequestMapping("/itemcat/list")
    @ResponseBody
    public Object getItemCatList(String callback) {
        CatResult catResult = itemCatService.getItemCatList();
        MappingJacksonValue mappingJacksonValue = new MappingJacksonValue(catResult);
        mappingJacksonValue.setJsonpFunction(callback);
        return mappingJacksonValue;
    }
通过spring4.0提供的工具类自动完成js的封装

相关推荐