<button onclick="one()">jquery jsonp</button>
<button onclick="two()">原生js jsonp</button>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
<script>
// jquery实现
function one() {
$.ajax({
url: '/test'
, dataType: 'jsonp'
, jsonp: 'callbackName' // 回调函数参数名称
// 回调函数参数值 默认jquery会生成随机名称
, jsonpCallback: 'test'
, data: {
name: 'lilei'
}
, success: function (data) {
console.log(data);
}
});
}
// 原生js实现
function two() {
jsonp({
url: '/test'
, callbackName: 'callbackName'
, data: {name: 'lilei'}
, callback: function (response) {
console.log(response);
}
});
}
// 手写jsonp函数
function jsonp(object) {
// 回调函数名
let callbackName = 'callbackName';
// url参数拼接
if (object.url.indexOf('?') < 0) {
object.url += '?';
}
// data参数拼接
for (let key in object.data) {
object.url += '&' + key + '=' + object.data[key];
}
object.url += '&' + object.callbackName + '=' + callbackName;
// 创建script标签
let script = document.createElement('script');
// 将方法注册到全局
window[callbackName] = function (response) {
try {
object.callback(response);
} catch (e) {
console.log(e);
} finally {
// 删除该函数和script元素
script.parentNode.removeChild(script);
delete window[callbackName];
}
}
script.src = object.url;
document.getElementsByTagName('body')[0].appendChild(script);
}
</script>
后端
@GetMapping("test")
public JSONPObject test(@RequestParam(required = false) String callbackName, String name) {
@Data
@AllArgsConstructor
class User {
private String name;
}
// 返回jackson的JSONPObject对象会解析成js对象的格式
// name({"data":"xxxx"]})而不是{"name": {"data":"xxxx"}}
return new JSONPObject(callbackName == null ? "name" : callbackName
, new HashMap<String, List<User>>() {{
put("data", new ArrayList<User>() {{
for (int i = 0; i < 2; i++) {
add(new User(i + name));
}
}});
}});
}