Skip to content

Instantly share code, notes, and snippets.

@lucabertolasi
Last active February 22, 2023 12:47
Show Gist options
  • Save lucabertolasi/48e15087088071b792a1bd1ff7617943 to your computer and use it in GitHub Desktop.
Save lucabertolasi/48e15087088071b792a1bd1ff7617943 to your computer and use it in GitHub Desktop.
[JavaScript] A vanilla JS url parser.
/**
* @license
* Copyright (c) 2017, Luca Bertolasi. All Rights Reserved.
*
* This source code is licensed under the terms of the MIT license,
* a copy of which can be found at https://choosealicense.com/licenses/mit/
*/
function urlParser(url) {
// fallback to location object if no arg has been provided
url = url === undefined ? window.location.href : url
// validate type
if (typeof url !== `string`
// validate pattern | source: https://gist.github.com/dperini/729294
|| url.match(/^(?:(?:https?|ftp):\/\/)( ?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,}))\.?)(?::\d{2,5})?(?:[/?#]\S*)?$/i) === null) {
throw new TypeError(`'${url}' is not a valid url`)
}
// parse url | source: https://news.ycombinator.com/item?id=12172180
const A = document.createElement('a')
A.href = url // "https://www.domain.io:8080/path?pa=1&ram=2#fragment"
// extract query params as map
const queryParams = new Map()
if (A.search.length > 0) {
A.search.split('?')[1].split('&').map(queryParam => {
[key, value] = queryParam.split('=')
queryParams.set(key, value)
})
}
// [alternative] extract query params as array
// const queryParams = A.search.length > 0 ? A.search.split('?')[1].split('&').map(queryParam => [key, value] = queryParam.split('=')) : []
return {
url: A.href, // "https://www.domain.io:8080/path?pa=1&ram=2#fragment"
origin: A.origin, // "https://www.domain.io:8080"
protocol: A.protocol, // "https"
host: A.host, // "www.domain.io:8080"
hostname: A.hostname, // "www.domain.io"
port: A.port, // "8080"
pathname: A.pathname, // "/path"
hash: A.hash, // "#fragment"
query_params: queryParams // {"pa" => "1", "ram" => "2"} // to get the number of query params, use property 'size'
// query_params: queryParams // [["pa", "1"], ["ram", "2"]] // to get the number of query params, use property 'length'
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment