关键词

JavaScript中模拟实现jsonp

JavaScript中模拟实现jsonp,需要遵循以下步骤:

1. 创建一个script标签

在DOM中创建一个script标签,并设置其src属性为需要跨域请求的URL,同时还需要设置一个callback参数,作为后端接口返回数据的回调函数名。

const script = document.createElement('script');
script.src = 'http://example.com/data?callback=getData';
document.body.appendChild(script);

2. 定义回调函数

定义一个全局函数,函数名与callback参数的值相同,该函数用于接收后端返回的数据,并处理它。在处理结束之后,可以根据需要将数据传递给其他函数进行展示或其他操作。

function getData(data) {
  // 处理数据
  console.log(data);
}

3. 后端返回数据

后端需要根据callback参数的值,在返回的数据中调用该函数,并传入需要返回的数据,此时会自动执行callback函数的代码。需要注意返回的数据格式为JS代码。

getData({
  name: '张三',
  age: 18,
  gender: '男'
});

示例1

例如,我们需要请求豆瓣电影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": "正在上映的电影-北京"
});

最后,在处理数据的函数中,我们可以根据需要将数据展示在页面上。

示例2

在一些极端情况下,由于后端不支持返回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

展开阅读全文