Ajax跨域请求解决方案:JSONP原理与Java后台实现

作者:百宝袋

时间:2026-10-22

浏览:548

本文详细解析Ajax跨域请求的JSONP解决方案。通过Java后台接收callback参数并封装JSON数据,前端利用script标签src无跨域限制的特性,指定dataType为jsonp进行请求。文章涵盖后台实现代码、前台两种调用写法及JSONP工作原理,帮助开发者解决跨域数据交互问题。

文章目录

近期在进行公众号前台开发时,遇到了Ajax跨域请求的难题。诸如省-市-县三级联动、汽车品牌-车系-车款三级联动查询等功能,均需调用外部接口(其他工程项目的接口)来完成。在此分享个人在后台开发人员协助下总结的跨域请求解决方案,旨在记录积累并供参考,欢迎提出意见或建议。

解决跨域请求需借助后台代码接收callback回调函数,并对JSON数据进行相应处理;前台则通过Ajax向服务器发送包含callback参数的请求,并将数据格式指定为JSONP。

一、后台对跨域请求进行处理

以CarBrandController.java(汽车品牌接口Java文件)为例,该方法主要根据level值查询对应的品牌、车系或车款。在此需处理跨域请求的回调函数接收:若返回的callback为null,则非跨域请求,无需特殊处理,直接打印JSON接口数据即可;若callback不为null,则表明是跨域请求,需对JSON数据进行特殊处理,即在JSON数据外层添加一对小括号包裹,具体实现见HttpAdapter.java文件中的printlnJSONObject方法。


public void json(HttpServletRequest request,HttpServletResponse response){ 
  Map<String,Object>map=new HashMap<String, Object>(); 
  String id = request.getParameter("id");      //接收ajax请求带过来的id 
  String level = request.getParameter("level");   //接收ajax请求带过来的level 
  String callback=request.getParameter("callback"); //接收ajax请求带过来的callback参数 
  if ("1".equals(level)) {             //如果level是'1',则查询第一级目录内容 
    map.put("results", this.carBrandService.findByAttr(null, "first_letter asc")); //调用查询方法,结果放入map 
  } else if ("2".equals(level)) {          //如果level是'2',则查询第二级目录内容 
    map.put("results", this.carSerieService.findByAttr("parent_id="+id, "first_letter asc"));//调用查询方法,结果放入map 
  } else if ("3".equals(level)) {          //如果level是'3',则查询第三极目录内容 
    map.put("results", this.carModelYearService.findByAttr("parent_id="+id, "jian_pin desc"));//调用查询方法,结果放入map 
  } 
  map.put("level",level); 
  if (null==callback) {               //如果接收的callback值为null,则是不跨域的请求,输出json对象 
    HttpAdapter.printlnObject(response, map); 
  }else{                      //如果接收的callback值不为null,则是跨域请求,输出跨域的json对象 
  HttpAdapter.printlnJSONPObject(response, map, callback); 
  } 
} 

在HttpAdapter.java(输出对象Java文件)中,printlnObject方法用于打印正常的JSON字符串;而printlnJSONObject方法则对JSON字符串进行了特殊处理以支持跨域。


/** 
 * 打印对象 
 * @param response 
 * @param object 
*/ 
public static void printlnObject(HttpServletResponse response,Object object){ 
  PrintWriter writer=getWriter(response); 
  writer.println(JSON.toJSONString(object)); 
} 
/** 
 * 打印跨域对象 
 * @param response 
 * @param object 
*/ 
public static void printlnJSONPObject(HttpServletResponse response,Object object,String callback){ 
  PrintWriter writer=getWriter(response); 
  writer.println(callback+"("+JSON.toJSONString(object)+")"); 
} 

二、前台ajax跨域请求数据

写法1:向服务器发送参数callback=?,同时指定dataType为'jsonp'格式。跨域请求时,指定的数据格式必须为JSONP形式。


function loadData(obj,level,id,value){ 
  $.ajax({  
    url:'http://192.168.1.106:8086/carBrand/json.html?level='+level+'&id='+id+'&callback=?',   //将callback写在请求url后面作为参数携带 
    type:'GET', 
    async:false, 
    dataType:'jsonp', 
    success:function(data){         
      console.log(data);             
      //其他处理(动态添加数据元素)       
  });    
}   

写法2:callback无需写在url中,但需指定jsonp参数为'callback',并给jsonpCallback参数赋予一个值。


function loadData(obj,level,id,value){ 
  $.ajax({  
    url:'http://192.168.1.106:8086/carBrand/json.html?level='+level+'&id='+id, 
    type:'GET', 
    dataType:'jsonp', 
    jsonp: 'callback',          //将callback写在jsonp里作为参数连同请求一起发送 
    jsonpCallback:'jsonpCallback1',    
    success:function(data){            
    console.log(data);       
}); }

上述两种写法含义相同,仅表现形式不同。

接下来补充JSONP的工作原理。

三、jsonp跨域的原理解析

JSONP的基本原理是动态添加一个<script>标签,由于script标签的src属性不受跨域限制,因此可实现跨域访问。这种方式与Ajax XmlHttpRequest协议无关。

JSONP是一个非官方协议,允许服务器端集成Script tags返回至客户端,通过javascript callback形式实现跨域访问JSONP(JSON with Padding)。受同源策略限制,XmlHttpRequest仅允许请求当前源(域名、协议、端口)的资源。通过HTML script标记进行跨域请求,并在响应中返回执行的script代码(可直接使用JSON传递JavaScript对象),这种跨域通讯方式称为JSONP。

jsonCallback函数jsonp1236827957501(....)是浏览器客户端注册的,用于在获取跨域服务器上的JSON数据后执行回调。

JSONP原理如下:

首先在客户端注册一个callback(如:'jsoncallback'),然后将该callback的名字(如:jsonp1236827957501)传给服务器。注意:服务端得到callback数值后,需用jsonp1236827957501(......)将待输出的JSON内容包裹起来,此时服务器生成的JSON数据才能被客户端正确接收。

随后以JavaScript语法生成一个function,function名字即为传递上来的参数'jsoncallback'的值jsonp1236827957501。

最后将JSON数据直接以入参方式放置到function中,从而生成一段JavaScript语法文档并返回给客户端。

客户端浏览器解析script标签,并执行返回的JavaScript文档。此时JavaScript文档数据作为参数,传入客户端预先定义好的callback函数(如上例中jQuery $.ajax()方法封装的success: function (json))中(动态执行回调函数)。

可以说JSONP的方式原理上与<script src="http://跨域/...xx.js"></script>一致(QQ空间大量采用此方式实现跨域数据交换)。JSONP是一种脚本注入(Script Injection)行为,因此存在一定的安全隐患。

注意,jQuery不支持通过POST方式进行跨域请求。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章