Ответ 1
Существует класс PageLinks в GitHub Java API, который показывает, как разбирать заголовок Link
.
API github отправляет данные разбиения на страницы для результатов json в заголовке http-ссылки:
Link: <https://api.github.com/repos?page=3&per_page=100>; rel="next",
<https://api.github.com/repos?page=50&per_page=100>; rel="last"
так как API github не является единственным API, использующим этот метод (я думаю), я хотел спросить, есть ли у кого-то полезный небольшой фрагмент, чтобы разобрать заголовок ссылки (и, например, преобразовать его в массив), чтобы я мог использовать это для моего приложения js.
i googled around, но не нашел ничего полезного в том, как анализировать разбиение на страницы из json API
Существует класс PageLinks в GitHub Java API, который показывает, как разбирать заголовок Link
.
Для этой цели существует модуль NPM файла заголовка parse-link; его источник можно найти на github под лицензией MIT (бесплатно для коммерческого использования).
Установка выполняется так же, как:
npm install parse-link-header
Использование выглядит следующим образом:
var parse = require('parse-link-header');
var parsed = parse('<https://api.github.com/repos?page=3&per_page=100>; rel="next", <https://api.github.com/repos?page=50&per_page=100>; rel="last"')
... после чего у него есть parsed.next
, parsed.last
и т.д.:
{ next:
{ page: '3',
per_page: '100',
rel: 'next',
url: 'https://api.github.com/repos?page=3&per_page=100' },
last:
{ page: '50',
per_page: '100',
rel: 'last',
url: ' https://api.github.com/repos?page=50&per_page=100' } }
Я нашел wombleton/link-headers в github. Похоже, что это сделано для браузера, а не для модуля npm, но похоже, что это не сложно будет изменить для работы в серверной среде. Он использует pegjs для генерации реального парсера RFC 5988, а не для разделения строк, поэтому он должен хорошо работать для любого заголовка ссылки, а не только для Github.
Я нашел этот Gist, который:
Заголовок Parse Github
Links
в JavaScript
Протестировано в API Github и возвращает объект вроде:
var results = {
last: "https://api.github.com/repositories/123456/issues?access_token=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX&state=open&since=2013-07-24T02%3A12%3A30.309Z&direction=asc&page=4"
next: "https://api.github.com/repositories/123456/issues?access_token=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX&state=open&since=2013-07-24T02%3A12%3A30.309Z&direction=asc&page=2"
};
Если вы можете использовать Python и не хотите реализовывать полную полную спецификацию, но нужно иметь что-то, что работает для Github API, а затем здесь мы идем:
import re
header_link = '<https://api.github.com/repos?page=3&per_page=100>; rel="next", <https://api.github.com/repos?page=50&per_page=100>; rel="last"'
if re.search(r'; rel="next"', header_link):
print re.sub(r'.*<(.*)>; rel="next".*', r'\1', header_link)
Я полностью понимаю, что это "технически" поток JavaScript
. Но, если вы похожи на меня и прибыли сюда с помощью Google , как разобрать заголовок Link, я подумал, что поделюсь своим решением для моего envinronment (С#).
public class LinkHeader
{
public string FirstLink { get; set; }
public string PrevLink { get; set; }
public string NextLink { get; set; }
public string LastLink { get; set;}
public static LinkHeader FromHeader(string linkHeader)
{
LinkHeader linkHeader = null;
if (!string.IsNullOrWhiteSpace(linkHeader))
{
string[] linkStrings = linkHeader.Split("\",");
if (linkStrings != null && linkStrings.Any())
{
linkHeader = new LinkHeader();
foreach (string linkString in linkStrings)
{
var relMatch = Regex.Match(linkString, "(?<=rel=\").+?(?=\")", RegexOptions.IgnoreCase);
var linkMatch = Regex.Match(linkString, "(?<=<).+?(?=>)", RegexOptions.IgnoreCase);
if (relMatch.Success && linkMatch.Success)
{
string rel = relMatch.Value.ToUpper();
string link = linkMatch.Value;
switch (rel)
{
case "FIRST":
linkHeader.FirstLink = link;
break;
case "PREV":
linkHeader.PrevLink = link;
break;
case "NEXT":
linkHeader.NextLink = link;
break;
case "LAST":
linkHeader.LastLink = link;
break;
}
}
}
}
}
return linkHeader;
}
}
Тестирование в консольном приложении с использованием примера GitHub Заголовок ссылки:
void Main()
{
string link = "<https://api.github.com/user/repos?page=3&per_page=100>; rel=\"next\",< https://api.github.com/user/repos?page=50&per_page=100>; rel=\"last\"";
LinkHeader linkHeader = LinkHeader.FromHeader(link);
}
Вот простая функция JavaScript, которая извлекает полезную информацию из ссылки в удобной нотации объекта.
var linkParser = (linkHeader) => {
let re = /<([^\?]+\?[a-z]+=([\d]+))>;[\s]*rel="([a-z]+)"/g;
let arrRes = [];
let obj = {};
while ((arrRes = re.exec(linkHeader)) !== null) {
obj[arrRes[3]] = {
url: arrRes[1],
page: arrRes[2]
};
}
return obj;
}
Это выведет результат как это ==>
{
"next": {
"url": "https://api.github.com/user/9919/repos?page=2",
"page": "2"
},
"last": {
"url": "https://api.github.com/user/9919/repos?page=10",
"page": "10"
}
}
Вот простой bash-скрипт с curl и sed, чтобы получить все страницы из длинного запроса
url="https://api.github.com/repos/$GIT_USER/$GIT_REPO/issues"
while [ "$url" ]; do
echo "$url" >&2
curl -Ss -n "$url"
url="$(curl -Ss -I -n "$url" | sed -n -E 's/Link:.*<(.*?)>; rel="next".*/\1/p')"
done > issues.json