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は知らないことがあると実感しました。

コメント