Reputation: 1835
This seems like a bug in this API, though I don't know where to report it. So I am posting here for help. Mozilla docs here URLSearchParams
If window.location.href
contains a #
then URLSearchParams.get
fails to retrieve the first search parameter
const location = 'http://localhost:3000/path?referrer=https://google.com';
const myURL = new URL(location).searchParams.get('referrer')
// myURL === 'https://google.com
// in one line:
(new URL('http://localhost:3000/path?referrer=https://google.com')).searchParams.get('referrer')
But this same example slightly tweaking the window location will fail
const location = 'http://localhost:3000/#/path?referrer=https://google.com';
const myURL = new URL(location).searchParams.get('referrer')
// myURL === null
// in one line
(new URL('http://localhost:3000/#/path?referrer=https://google.com')).searchParams.get('referrer')
This example is using new URL(location).searchParams.get
but will yield the exact same functionality if you tweak it to using new URLSearchParams(...).get
Upvotes: 17
Views: 16602
Reputation: 2210
I know this issue is a bit old, but I ran into the same issue recently and created a simple function to fix the Url hash & search params:
function fixUrlHash(url) {
let fixedUrl = new URL(url);
let search = url.search;
let hash = url.hash;
const position = url.hash.indexOf('?');
if(search.length <= 1 && position >= 0) {
search = hash.substr(position);
hash = hash.substr(0, position);
fixedUrl.hash = hash;
fixedUrl.search = search;
fixedUrl.href = fixedUrl.toString();
}
return fixedUrl;
}
This simply returns a new URL object with the fixed hash & search params. After you get the fixed URL value, you can load the new URL in the browser if original URL is the browser location.
Upvotes: 2
Reputation: 19301
In URL standards, #
introduces a fragment component that has no special meaning to the transport protocol and is treated as secondary or "user specified" information whose semantics are treated as unknown. The #
and everything following it in the URL is passed to the client application (e.g. HTML browser) without interpretation. You can access the fragment value in JavaScript using window.location.hash
.
Any URL parameters must precede a fragment identifier or they will be included in fragment content and not parsed as parameters.
A #
could be included in the URL path or parameters, but would need to be percentage escaped as %23
. I would strongly advise against writing a router or creating a server side folder for static content that contains #
in the path, even if technically possible.
Allowing users to enter #
in form inputs would normally be handled automatically by encoding the input value with encodeURIComponent()
before submitting the form.
Data URLs that have been formulated using clear text of a particular MIME type need to percentage escape any and every #
within the text to avoid truncating data represented by the URL.
Upvotes: 9
Reputation: 81
Just replace #
with /
let location = 'http://localhost:3000/#/path?referrer=https://google.com';
location = location.replace('#', '/');
let myURL = new URL(location).searchParams.get('referrer')
console.log(myURL)
Upvotes: 5