3

The LinkedIn guide for setting up auth with the Javascript SDK shows a code sample but it's very confusing as to what the author actually means.

<script type="text/javascript" src="//platform.linkedin.com/in.js">
    api_key:   [API_KEY]
    onLoad:    [ONLOAD]
    authorize: [AUTHORIZE]
    lang:      [LANG_LOCALE]
</script>

It's not valid JS, there's no commas, and quotes are omitted. Also, the example shows brackets but these have to be omitted or an error will be thrown. A real-world example would alleviate the confusion, but, of course, none is provided.

Here's a valid example but using a made-up API key (the API key is the same thing as the client ID – the guide doesn't bother to explain that)

<script type="text/javascript" src="//platform.linkedin.com/in.js">
    api_key: 93h7nnksxj3ccd
    authorize: true
    lang: en_US
</script>

As you can see with this other SO question, I'm not the only one who is confused, this guy thought the same thing I did, which is that quotes would be needed.

How does this code actually work? Is this considered valid syntax for a script tag which has the type text/javascript?

[edit] Re: possible duplicate, seems this is not. See the selected answer. [/edit]

rm.rf.etc
  • 884
  • 2
  • 8
  • 20
  • Possible duplicate of [Script tag with both external source and body](https://stackoverflow.com/questions/8676093/script-tag-with-both-external-source-and-body) – str May 27 '18 at 20:47

1 Answers1

1

The external script is reading and parsing the script tag's innerHTML directly. This is covered by this blog article by Roger Hu:

The article examines LinkedIn's JavaScript and identifies the parser used:

Basically the code below appears to extract out the innerHTML and then set the variables r and K to be the key/value pairs. White spaces are removed with the replace() function.

Here is a brief description, followed by longer excerpts:

Data is extracted raw from the innerHTML:

l = f.innerHTML.replace(A, n)

A regular expression for each line is defined:

g = (/^[\s]*(.*?)[\s]*:[\s]*(.*)[\s]*$/),

It is used per line, setting r to the key and and K to the value.

W = s.match(g);
r = W[1].replace(A, n);
K = W[2].replace(A, n)

If there is no match, it provides the following error:

script tag contents must be key/value pairs separated by a colon.

Larger excerpt:

for (U = 0, q = t.length; U < q; U++) {
    var f = t[U];
    if (!m.test(f.src)) {
        continue
    }
    if (b.test(f.src)) {
        c = true
    }
    try {
        l = f.innerHTML.replace(A, n)
    } catch (z) {
        try {
            l = f.text.replace(A, n)
        } catch (y) {}
    }
}
l = l.replace(J, "$1").replace(A, n).replace(F, n);
ab = C.test(l.replace(j, n));
for (var U = 0, T = l.split(k), q = T.length; U < q; U++) {
    var s = T[U];
    if (!s || s.replace(j, n).length <= 0) {
        continue
    }
    try {
        W = s.match(g);
        r = W[1].replace(A, n);
        K = W[2].replace(A, n)
    } catch (Y) {
        if (!ab) {
            console.warn("script tag contents must be key/value pairs separated by a colon. Source: " + Y)
        }
        continue
    }
    N(r, K)
}

The set of regular expressions is defined at the top of the script:

var S = {
        "bootstrapInit": +new Date()
    },
    p = document,
    m = (/^https?:\/\/.*?linkedin.*?\/in\.js.*?$/),
    b = (/async=true/),
    D = (/^https:\/\//),
    J = (/\/\*((?:.|[\s])*?)\*\//m),
    F = (/\r/g),
    j = (/[\s]/g),
    g = (/^[\s]*(.*?)[\s]*:[\s]*(.*)[\s]*$/),
    x = (/_([a-z])/gi),
    A = (/^[\s]+|[\s]+$/g),
    u = (/^[a-z]{2}(_)[A-Z]{2}$/),
    C = (/suppress(Warnings|_warnings):true/gi),
    d = (/^api(Key|_key)$/gi),
Grokify
  • 15,092
  • 6
  • 60
  • 81