Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Parse Github `Links` header in JavaScript
/*
* parse_link_header()
*
* Parse the Github Link HTTP header used for pageination
* http://developer.github.com/v3/#pagination
*/
function parse_link_header(header) {
if (header.length == 0) {
throw new Error("input must not be of zero length");
}
// Split parts by comma
var parts = header.split(',');
var links = {};
// Parse each part into a named link
_.each(parts, function(p) {
var section = p.split(';');
if (section.length != 2) {
throw new Error("section could not be split on ';'");
}
var url = section[0].replace(/<(.*)>/, '$1').trim();
var name = section[1].replace(/rel="(.*)"/, '$1').trim();
links[name] = url;
});
return links;
}
@AaronAcerboni

This comment has been minimized.

Copy link

AaronAcerboni commented Nov 12, 2012

Do you know if this can be used for parsing general (non gh specific) link headers?

@ejain

This comment has been minimized.

Copy link

ejain commented Nov 28, 2012

No, this code won't work for headers with links that contain , or ;.

@Gilmargolin

This comment has been minimized.

Copy link

Gilmargolin commented May 29, 2014

FOR THOSE WHO NEED IT WITHOUT JQUERY

function parse_link_header(header) {
if (header.length == 0) {
throw new Error("input must not be of zero length");
}

// Split parts by comma
var parts = header.split(',');
var links = {};
// Parse each part into a named link
for(i=0;i<parts.length;i++)
{
var section = parts[i].split(';');
if (section.length != 2) {
throw new Error("section could not be split on ';'");
}
var url = section[0].replace(/<(.)>/, '$1').trim();
var name = section[1].replace(/rel="(.
)"/, '$1').trim();
links[name] = url;
}

return links;
}

@JBKahn

This comment has been minimized.

Copy link

JBKahn commented Jun 16, 2015

Put @Gilmargolin 's code inside a code block for readability and fixed it up. No jquery or underscore here.

function parse_link_header(header) {
    if (header.length === 0) {
        throw new Error("input must not be of zero length");
    }

    // Split parts by comma
    var parts = header.split(',');
    var links = {};
    // Parse each part into a named link
    for(var i=0; i<parts.length; i++) {
        var section = parts[i].split(';');
        if (section.length !== 2) {
            throw new Error("section could not be split on ';'");
        }
        var url = section[0].replace(/<(.*)>/, '$1').trim();
        var name = section[1].replace(/rel="(.*)"/, '$1').trim();
        links[name] = url;
    }
    return links;
}
@jankal

This comment has been minimized.

Copy link

jankal commented Jun 16, 2015

If someone needs this the PHP way...:

function parseLinkHeader($header) {
    if (strlen($header) == 0) {
        throw new \Exception("input must not be of zero length");
    }

    $parts = explode(',', $header);
    $links = [];

    foreach($parts as $p) {
        $section = explode(';', $p);
        if (count($section) != 2) {
            throw new \Exception("section could not be split on ';'");
        }
        $url = trim(preg_replace("/<(.*)>/", '$1', $section[0]));
        $name = trim(preg_replace("/rel=\"(.*)\"/", '$1', $section[1]));
        $links[$name] = $url;
    }
    return $links;
}
@kael

This comment has been minimized.

Copy link

kael commented Oct 5, 2018

parse_link_header doesn't work with:

'<http://mementoweb.org/wikipedia/>;rel="original", <http://mementoarchive.lanl.gov/twa/memento/20130919212835/http://mementoweb.org/wikipedia/>;rel="memento"; datetime="Thu, 19 Sep 2013 21:28:35 GMT", <http://mementoarchive.lanl.gov/twa/memento/20160920160128/http://mementoweb.org/wikipedia/>;rel="memento last"; datetime="Tue, 20 Sep 2016 16:01:28 GMT", <http://mementoarchive.lanl.gov/twa/memento/20130912190257/http://mementoweb.org/wikipedia/>;rel="memento first"; datetime="Thu, 12 Sep 2013 19:02:57 GMT", <http://mementoarchive.lanl.gov/twa/memento/20130919220632/http://mementoweb.org/wikipedia/>;rel="memento next"; datetime="Thu, 19 Sep 2013 22:06:32 GMT", <http://mementoarchive.lanl.gov/twa/memento/20130919212641/http://mementoweb.org/wikipedia/>;rel="memento prev"; datetime="Thu, 19 Sep 2013 21:26:41 GMT" , <http://mementoarchive.lanl.gov/twa/timemap/link/http://mementoweb.org/wikipedia/>;rel="timemap"; type="application/link-format" , <http://mementoarchive.lanl.gov/twa/timegate/http://mementoweb.org/wikipedia/>;rel="timegate"'.

I'm using parse-link-header.

@yurynix

This comment has been minimized.

Copy link

yurynix commented Apr 8, 2019

Handle the comma inside quotes with lookahead/lookbehind (only works on JS engines that support it)

function parseLinkHeader(header) {
    if (header.length === 0) {
        throw new Error("input must not be of zero length");
    }

    // Split parts by comma and parse each part into a named link
    return header.split(/(?!\B"[^"]*),(?![^"]*"\B)/).reduce((links, part) => {
        const section = part.split(/(?!\B"[^"]*);(?![^"]*"\B)/);
        if (section.length < 2) {
            throw new Error("section could not be split on ';'");
        }
        const url = section[0].replace(/<(.*)>/, '$1').trim();
        const name = section[1].replace(/rel="(.*)"/, '$1').trim();

        links[name] = url;

        return links;
    }, {});
}
@patarapolw

This comment has been minimized.

Copy link

patarapolw commented Aug 20, 2019

Can't it be as simple as?

function parseLink(s) {
  const output = {};
  const regex = /<([^>]+)>; rel="([^"]+)"/g;

  let m;
  while (m = regex.exec(s)) {
    const [_, v, k] = m;
    output[k] = v;
  }

  return output;
}

Usage: parseLink(headers.get("link"))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.