JavaScript中模拟实现jsonp,需要遵循以下步骤:
在DOM中创建一个script标签,并设置其src属性为需要跨域请求的URL,同时还需要设置一个callback参数,作为后端接口返回数据的回调函数名。
const script = document.createElement('script');
script.src = 'http://example.com/data?callback=getData';
document.body.appendChild(script);
定义一个全局函数,函数名与callback参数的值相同,该函数用于接收后端返回的数据,并处理它。在处理结束之后,可以根据需要将数据传递给其他函数进行展示或其他操作。
function getData(data) {
// 处理数据
console.log(data);
}
后端需要根据callback参数的值,在返回的数据中调用该函数,并传入需要返回的数据,此时会自动执行callback函数的代码。需要注意返回的数据格式为JS代码。
getData({
name: '张三',
age: 18,
gender: '男'
});
例如,我们需要请求豆瓣电影API,获取热映电影的数据,并展示在页面上。首先,我们创建一个script标签,定义好回调函数,并通过callback参数传递给后端:
const script = document.createElement('script');
script.src = 'https://api.douban.com/v2/movie/in_theaters?callback=handleData';
document.body.appendChild(script);
function handleData(data) {
console.log(data);
}
然后,后端根据callback参数调用该函数,并将数据格式化为JS代码后返回给前端:
handleData({
"count": 20,
"start": 0,
"total": 39,
"subjects": [
{
"rating": {
"max": 10,
"average": 7.4,
"stars": "40",
"min": 0
},
"genres": [
"动作",
"科幻"
],
"title": "蜘蛛侠:英雄远征",
"casts": [
{
"avatars": {
"small": "https://img3.doubanio.com/view/celebrity/s_ratio_celebrity/public/p1360451470.99.webp",
"large": "https://img3.doubanio.com/view/celebrity/s_ratio_celebrity/public/p1360451470.99.webp",
"medium": "https://img3.doubanio.com/view/celebrity/s_ratio_celebrity/public/p1360451470.99.webp"
},
"name_en": "Tom Holland",
"name": "汤姆·赫兰德",
"alt": "https://movie.douban.com/celebrity/1339225/",
"id": "1339225"
},
{
"avatars": {
"small": "https://img3.doubanio.com/view/celebrity/s_ratio_celebrity/public/p1507059488.68.webp",
"large": "https://img3.doubanio.com/view/celebrity/s_ratio_celebrity/public/p1507059488.68.webp",
"medium": "https://img3.doubanio.com/view/celebrity/s_ratio_celebrity/public/p1507059488.68.webp"
},
"name_en": "Zendaya",
"name": "赞达亚",
"alt": "https://movie.douban.com/celebrity/1378051/",
"id": "1378051"
}
],
"collect_count": 151249,
"original_title": "Spider-Man: Far from Home",
"subtype": "movie",
"directors": [
{
"avatars": {
"small": "https://img1.doubanio.com/view/celebrity/s_ratio_celebrity/public/p1433934340.49.webp",
"large": "https://img1.doubanio.com/view/celebrity/s_ratio_celebrity/public/p1433934340.49.webp",
"medium": "https://img1.doubanio.com/view/celebrity/s_ratio_celebrity/public/p1433934340.49.webp"
},
"name_en": "Jon Watts",
"name": "乔恩·沃茨",
"alt": "https://movie.douban.com/celebrity/1330053/",
"id": "1330053"
}
],
"year": "2019",
"images": {
"small": "https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2558261313.webp",
"large": "https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2558261313.webp",
"medium": "https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2558261313.webp"
},
"alt": "https://movie.douban.com/subject/27032767/",
"id": "27032767"
},
...
],
"title": "正在上映的电影-北京"
});
最后,在处理数据的函数中,我们可以根据需要将数据展示在页面上。
在一些极端情况下,由于后端不支持返回callback函数,或者返回的数据不规范,这时候需要手动写一个callback函数来处理。
例如,我们需要请求某个站点的数据,该站点不支持jsonp调用,只能通过Ajax跨域请求,但是这个网站的CORS规则没有设置,无法进行跨域请求。这时候,我们可以手动声明一个全局函数,在请求数据之前,先通过script标签把该函数注入到页面中,请求数据返回之后,再通过该函数进行处理。
window.handleData = function(data) {
console.log(data);
}
const script = document.createElement('script');
script.innerHTML = `handleData({name: 'abc'})`;
document.body.appendChild(script);
这里需要声明一个全局的handleData函数,并将其注入到页面中。创建一个script标签,同时将注入的代码也放到script标签内部。这样,就可以在请求数据返回之后,通过该全局函数进行数据的处理和展示。
本文链接:http://task.lmcjl.com/news/15840.html