Как напечатать все имена персонажей из игры «Игра престолов Api» в пагинации |Траверса с разбивкой по страницам API в JS - PullRequest
0 голосов
/ 05 июня 2018

Здравствуйте, я пытаюсь создать сторонний проект с использованием API игры престолов.Из любопытства хочу напечатать все имена персонажей из https://www.anapioficeandfire.com/api/characters.

Из заголовков ответов и документации (https://anapioficeandfire.com/Documentation#pagination), Я вижу, что Api имеет 214 страниц. Как мне получить имена персонажей со всех этих 214 страниц.

Моя текущая попытка позволяет мнеполучить имена только из первых 10 объектов

Вот моя попытка:

(function() {
  var req = new XMLHttpRequest();

  req.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      console.log(req.getResponseHeader("link"));
      let charObj = JSON.parse(this.responseText);
      for (let i = 0; i < charObj.length; i++) {
        let p = document.createElement("p");
        let name = document.createTextNode(charObj[i].name);
        p.appendChild(name);
        document.body.appendChild(p);
      }
    }
  };
  req.open("GET", "https://www.anapioficeandfire.com/api/characters", true);
  req.send();
})();

Ответы [ 2 ]

0 голосов
/ 05 июня 2018

Использование fetch.Существует свойство link Header, которое сообщает вам next, prev и last URL-адреса конечной точки, которую вы просматриваете.

Вы должны объединять / упорядочивать запросы таким образом, чтобыВы получаете первый URL, получаете URL next и делаете вызов на следующую страницу.Продолжайте делать это до тех пор, пока у вас не закончатся страницы и вы не соберете все символы таким образом.

Я заметил, что не у всех есть name, поэтому я выбираю либо имя, либо первый псевдоним.

Также, чтобы облегчить доступ к серверу, я ограничил глубину процесса до 3 запросов.Вы должны удалить это, если вы не хотите лимит.

function parseHeaders(res) {
    return res.headers.get("link").split(",").reduce((acc, link) => {
        const props = /^\<(.+)\>; rel="(.+)"$/.exec(link.trim());
        if (!props) {
            console.warn("no match");
            return acc;
        }
        acc[props[2]] = props[1];
        return acc;
    }, {});
}

async function go(url, depth = 0) {
    /*
     * You don't need this, this is just to alleviate load on the API's server
     * You should remove all the stuff about depth whenever you use this,
     * it just limits the total number of requests to fire to 3 which is nice
     * since it looks like there would be like 215 requests if you didn't do this.
     */
    if (depth >= 3) return [];

    const res = await fetch(url);
    const props = parseHeaders(res);
    const data = await res.json();
    const characters = data.map(character => character.name || character.aliases[0]);

    if (props.next) {
        const newCharacters = await go(props.next, depth + 1);
        characters.push(...newCharacters);
    }

    return characters;
}

(async function() {
    const characters = await go("https://www.anapioficeandfire.com/api/characters");
    console.log(characters);
}());
0 голосов
/ 05 июня 2018

В документации видно, что вы можете указать page number и pageSize, однако:

Вы можете указать, сколько элементов вы хотите получить на странице, максимум составляет 50

Добавив эти параметры в конце вашего url, вы можете получить максимум50 элементов на страницу, добавьте page=1&pageSize=50 (так как исходный размер страницы 10)

Но вы можете поместить свой запрос в цикл, чтобы получить все страницы от 1 до 214, 10 за раз:

(освободить IFEE и вызвать функцию в цикле for)

function getItems(page) {
  var req = new XMLHttpRequest();

  req.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      //console.log(req.getResponseHeader("link"));
      let charObj = JSON.parse(this.responseText);
      for (let i = 0; i < charObj.length; i++) {
        let p = document.createElement("p");
        let name = document.createTextNode(charObj[i].name);
        p.appendChild(name);
        document.body.appendChild(p);
      }
    }
  };
  req.open("GET", "https://www.anapioficeandfire.com/api/characters?page=" + page + "&pageSize=10", true);
  req.send();
};

for (let i = 1; i <= 214; i++) {
  getItems(i)
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...