JavaScriptでlocationオブジェクトのようなオブジェクトを作成する関数を作ってみた

locationオブジェクトは現在表示しているページのURLの情報を含んだオブジェクトです(参考:window.location – Web API インターフェイス | MDN)。

ただ、リファラ(document.referrer)のように、自身のページ以外のURLもlocationオブジェクトのような情報を取得したいと思ったので、試しに作ってみました。正規表現使ったらもっと簡素にできるかもしれませんが、地道に検索して抜き出して……という感じで作っていきました。

function createLikeLocationObject(url){
	var obj = {
		hash : '', // ハッシュ値
		host : '', // ホスト値
		hostname : '', // ホスト名
		href : '', // 参照URL
		origin : '', // オリジン
		param : {}, // GETパラメータオブジェクト
		pathname : '', // パス名
		port : '', // ポート番号
		protocol : '', // プロトコル
		search : '', // GETパラメータ
		toString : function(){ return this.href; }
	};
	// JavaScript - 相対URLを絶対URL(URI)に変換する方法について - Qiita http://qiita.com/sounisi5011/items/e24d0e1dfd71c5dd528e
	var e = document.createElement('a');
	e.href = url;
	obj.href = e.href;
	
	// JavaScriptでGETパラメーターを取得する - Qiita http://qiita.com/Evolutor_web/items/c9b940f752883676b35d
	// 上記ページを参考
	var getParams = function(search){
		var vars = {}; 
		var param = search.substring(1).split('&');
		for(var i = 0; i < param.length; i++) {
			var keySearch = param[i].search(/=/);
			var key = '';
			if(keySearch != -1) key = param[i].slice(0, keySearch);
			var val = param[i].slice(param[i].indexOf('=', 0) + 1);
			if(key != '') vars[key] = decodeURI(val);
		} 
		return vars; 
	}
	
	var href = obj.href;
	
	var hashIndex = href.search('#');
	if( hashIndex !== -1 ){
		obj.hash = href.slice(hashIndex);
		href = href.substr(0, hashIndex);
	}
	
	var searchIndex = href.search('[?]');
	if( searchIndex !== -1 ){
		obj.search = href.slice(searchIndex);
		href = href.substr(0, searchIndex);
	}
	
	var protocolIndex = href.search('://');
	if( protocolIndex !== -1 ){
		obj.protocol = href.slice(0, protocolIndex+1);
		href = href.slice(protocolIndex+3);
	}
	
	var hostIndex = href.search('/');
	if(hostIndex === -1){
		obj.host = href;
		obj.pathname = '';
	}else{
		obj.host = href.slice(0, hostIndex);
		obj.pathname = href.slice(hostIndex);
	}
	
	var portIndex = obj.host.search(':');
	if(portIndex === -1){
		obj.hostname = obj.hostname;
		obj.port = '';
	}else{
		obj.hostname = obj.host.slice(0, portIndex);
		obj.port = obj.host.slice(portIndex+1);
	}
	
	obj.origin = obj.protocol + '//' + obj.host;
	
	obj.param = getParams(obj.search);
	
	return obj;
}

引数にURLやパスを入れるとlocationオブジェクトのようなオブジェクトを返す関数です。ついでに、GETパラメータもオブジェクトとして取得するようにしています(参考:JavaScriptでGETパラメーターを取得する - Qiita)。

試しに、node.jsで"http://amyu.localhost:9000/hogehoge/index.html?a=a&b&c=c#zzz"というURLにアクセスできるようにし、locationオブジェクトと今回作った関数を比較してみました。開発者ツールのコンソールでcopyコマンドを利用し、それをペーストした結果です。

// locationオブジェクト
copy(location)
{
  "ancestorOrigins": {
    "length": 0
  },
  "origin": "http://amyu.localhost:9000",
  "hash": "#zzz",
  "search": "?a=a&b&c=c",
  "pathname": "/hogehoge/index.html",
  "port": "9000",
  "hostname": "amyu.localhost",
  "host": "amyu.localhost:9000",
  "protocol": "http:",
  "href": "http://amyu.localhost:9000/hogehoge/index.html?a=a&b&c=c#zzz"
}

// createLikeLocationObject関数
copy(createLikeLocationObject(location.href))
{
  "hash": "#zzz",
  "host": "amyu.localhost:9000",
  "hostname": "amyu.localhost",
  "href": "http://amyu.localhost:9000/hogehoge/index.html?a=a&b&c=c#zzz",
  "origin": "http://amyu.localhost:9000",
  "param": {
    "a": "a",
    "c": "c"
  },
  "pathname": "/hogehoge/index.html",
  "port": "9000",
  "protocol": "http:",
  "search": "?a=a&b&c=c"
}

順番が異なっているのでわかりづらいですが、あってるようです。

ところで、今回この関数を作るにあたって、相対URLでも絶対URLに変換したうえで取得するようにしよう。そうすればaタグに記述している相対URLの情報も取得できるし。と思って調べたらaタグのhrefプロパティを取得すれば相対URLを入れていても絶対URLで取得できるということが分かりました(参考:JavaScript - 相対URLを絶対URL(URI)に変換する方法について - Qiita)。

なんだ、そんな簡単に相対URLを絶対URLに変換できるんだー! と驚きました。ただ、ここで試しておくべきだったんです……。a要素のプロパティに『hostname』や『pathname』があるのかどうかということを……。そうです。上記みたいな関数を作らなくても、a要素のプロパティにあるようなんです……。さっき知りました……。

var a = document.createElement('a');
a.href = 'http://amyu.localhost:9000/hogehoge/index.html?a=a&b&c=c#zzz';
console.log(a.hash); //=> '#zzz'
console.log(a.hostname); //=> 'amyu.localhost'
console.log(a.href); //=> 'http://amyu.localhost:9000/hogehoge/index.html?a=a&b&c=c#zzz'
console.log(a.origin); //=> 'http://amyu.localhost:9000'
console.log(a.pathname); //=> '/hogehoge/index.html'
console.log(a.port); //=> '9000'
console.log(a.protocol); //=> 'http:'
console.log(a.search); //=> '?a=a&b&c=c'

参考:Location - Web API インターフェイス | MDN

まだまだJavaScriptは知らないことがあると実感しました。

コメント

タイトルとURLをコピーしました