Парсинг URL с помощью JavaScript

/
2015-04-01 13:07
Просмотры: 15137

Часто возникает ситуация, когда нужно отпарсить URL на клиенте. Сохранить какие то параметры перехода в cookie, перенаправить пользователя на другой ресурс в зависимости от параметров в URL. Встроенной функции, такой как parse_url в PHP к сожалению нет. Конечно это можно сделать все вручную с привлечением регулярных выражений, например так:

function parse_url(href) {
    var match = href.match(/^(https?\:)\/\/(([^:\/?#]*)(?:\:([0-9]+))?)(\/[^?#]*)(\?[^#]*|)(#.*|)$/);
    return match && {
        protocol: match[1],
        host: match[2],
        hostname: match[3],
        port: match[4],
        pathname: match[5],
        search: match[6],
        hash: match[7]
    }
}

Можно так же воспользоваться эквивалентом parse_url в PHP из сайта http://phpjs.org, который специализируется на написании JavaScript функций эквивалентов PHP.

function parse_url(str, component) {
	// example 1: parse_url('http://username:password@hostname/path?arg=value#anchor');
	// returns 1: {scheme: 'http', host: 'hostname', user: 'username', pass: 'password', path: '/path', query: 'arg=value', fragment: 'anchor'}

	var query, key = [
	'source', 'scheme', 'authority', 'userInfo', 
	'user', 'pass', 'host', 'port', 'relative', 'path', 
	'directory', 'file', 'query', 'fragment'
	],
	ini = (this.php_js && this.php_js.ini) || {},
	mode = (ini['phpjs.parse_url.mode'] &&
	ini['phpjs.parse_url.mode'].local_value) || 'php',
	parser = {
		php: /^(?:([^:\/?#]+):)?(?:\/\/()(?:(?:()(?:([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?))?()(?:(()(?:(?:[^?#\/]*\/)*)()(?:[^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
		strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
		loose: /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/\/?)?((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/ // Added one optional slash to post-scheme to catch file:/// (should restrict this)
	};

	var m = parser[mode].exec(str),
	uri = {},
	i = 14;
	while (i--) {
		if (m[i]) {
			uri[key[i]] = m[i];
		}
	}

	if (component) {
		return uri[component.replace('PHP_URL_', '').toLowerCase()];
	}
	if (mode !== 'php') {
		var name = (ini['phpjs.parse_url.queryKey'] &&
		ini['phpjs.parse_url.queryKey'].local_value) || 'queryKey';
		parser = /(?:^|&)([^&=]*)=?([^&]*)/g;
		uri[name] = {};
		query = uri[key[12]] || '';
		query.replace(parser, function($0, $1, $2) {
			if ($1) {
				uri[name][$1] = $2;
			}
		});
	}
	delete uri.source;
	return uri;
}

Но наиболее изысканный способ парсинга URl можно сделать так:

function parse_url(url){
	// example 1: parse_url('http://example.com:3000/pathname/?search=test#hash');
	// returns 1: {protocol: 'http:', hostname: 'example.com', port: '3000', pathname: '/pathname/', search: '?search=test', hash: '#hash', host: 'example.com:3000'}
	
	var parser = document.createElement('a');
	parser.href = url;

	return parser;
}

parser = parse_url('http://example.com:3000/pathname/?search=test#hash')
parser.protocol; // => "http:"
parser.hostname; // => "example.com"
parser.port; // => "3000"
parser.pathname; // => "/pathname/"
parser.search; // => "?search=test"
parser.hash; // => "#hash"
parser.host; // => "example.com:3000"

Добавить комментарий

Все комментарии

Дмитрий
24 марта 2016 12:36
Да, но только там в переменую нужно другую пихать не "parser_url" а просто "parser"; Спасибо, помогло
Ответить
comments powered by Disqus