Question

My HTML block as follows,

<html>
<title>Example</title>
<head>
</head>
<body>
        <h2>Profile Photo</h2>
    <div id="photo-container">Photo will load here</div>
    <script type='text/javascript' src='http://example.com/js/coverphoto.js?name=johndoe'></script>
</body>
</html>

and I have saved this file as test.html. In JavaScript source the name will be dynamic. I want to collect the name in coverphoto.js. Tried in coverphoto.js as,

window.location.href.slice(window.location.href.indexOf('?') + 1).split('&')

but it is getting the html file name (test.html) only. How can I retrieve the name key from http://example.com/js/coverphoto.js?name=johndoe in coverphoto.js?

Was it helpful?

Solution

To get the URL of the current JavaScript file you can use the fact that it will be the last <script> element currently on the page.

var scripts = document.getElementsByTagName('script');
var script = scripts[scripts.length - 1];
var scriptURL = script.src;

Please note that this code will only work if it executes directly within the JS file, i.e. not inside a document-ready callback or anything else that's called asynchronously. Then you can use any "get querystring parameter" JS (but make sure to replace any location.search references in there) to extract the argument.

I'd suggest you to put the value in a data-name argument though - that way you can simply use e.g. script.getAttribute('data-name') to get the value.

OTHER TIPS

You can use the stack trace technique.
This technique will detect the source of the JS file the script is running from and it doesn't depend on the way you have injected the script. It can be dynamically injected (ajax) or in whatever method you can think of.

Just use the following code in your JS file:

const STACK_TRACE_SPLIT_PATTERN = /(?:Error)?\n(?:\s*at\s+)?/;
const STACK_TRACE_ROW_PATTERN1 = /^.+?\s\((.+?):\d+:\d+\)$/;
const STACK_TRACE_ROW_PATTERN2 = /^(?:.*?@)?(.*?):\d+(?::\d+)?$/;

const getFileParams = () => {
    const stack = new Error().stack;
    const row = stack.split(STACK_TRACE_SPLIT_PATTERN, 2)[1];
    const [, url] = row.match(STACK_TRACE_ROW_PATTERN1) || row.match(STACK_TRACE_ROW_PATTERN2) || [];
    if (!url) {
        console.warn("Something went wrong. This probably means that the browser you are using is non-modern. You should debug it!");
        return;
    }
    try {
        const urlObj = new URL(url);
        return urlObj.searchParams;
    } catch (e) {
        console.warn(`The URL '${url}' is not valid.`);
    }
};

const params = getFileParams();
if ( params ) {
    console.log(params.get('name'));
}

Note: The params.searchParams will not work for IE browser, instead you can use params.search. But, for the sake of you nerves don't. Whoever is still using IE in 2020, just let him suffer.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top