简体   繁体   中英

URLSearchParams fails to get first parameter when '#' is in url

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

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 ( eg 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.

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.

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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM