イントロダクション
ハッシュ(#)を URL に付与して、Web ページ内の特定のアンカーにジャンプするようにすることができます。これは非常に便利な機能ですが、現在表示している Web ページの URL を基に、JavaScript などで何らかの処理を行う場合には、この URL のハッシュ(#)を考慮していないと困ったことが起こったりします。
URL にハッシュ(#)が付与されていると、同じWebページを示しているURLなのに、単純な文字列比較では別の Web ページのように見えてしまうからです。
今回は、現在ブラウザで表示している Web ページの URL にハッシュが(#)が付与されている場合でも、ハッシュ(#)を含まない URL が取得できる方法について考えてみることにします。
ハッシュ(#)を含まない現在のページのURLを取得する
現在ブラウザで表示している Web ページの URL は location オブジェクトに収められています。
window.location - Web API インターフェイス | MDN
https://developer.mozilla.org/ja/docs/Web/API/window.location
https://developer.mozilla.org/ja/docs/Web/API/window.location
document.location - Web API インターフェイス | MDN
https://developer.mozilla.org/ja/docs/Web/API/document.location
https://developer.mozilla.org/ja/docs/Web/API/document.location
location オブジェクトからどのような情報を取得できるのかは、上記の window.location に詳しく記載されています。
location オブジェクトのプロパティには、ハッシュ(#)を含まないURLをズバリ取得するためのものはありませんが、複数のプロパティを組み合わせることで、ハッシュ(#)を含まないURLを生成することができます。
考え方としては、location オブジェクトの各プロパティを組み立てて、ハッシュ(#)を含まないURLを生成する方法と、location オブジェクトの完全なURL(href)から、ハッシュ(#)部分を削除することで、ハッシュ(#)を含まないURLを生成する方法(現時点では、まだ非推奨)の 2 つがあります。
location オブジェクトの各プロパティを組み立てて、ハッシュ(#)を含まないURLを生成
location オブジェクトの各プロパティを組み立てて、ハッシュ(#)を含まないURLを生成するには、次の JavaScript コードを使用します。JavaScript コード:
var new_url = location.protocol + "//" + location.host + location.pathname + location.search;
実際の URL を使用して、ハッシュ(#)が含まれないURLが生成で来たかどうかをチェックしてみましょう。
テストに使用するURL:
http://upa-pc.blogspot.jp/2015/02/pc-life-good-items.html?m=1#more
実行結果:
new_url : "http://upa-pc.blogspot.jp/2015/02/pc-life-good-items.html?m=1"
location オブジェクトの完全なURL(href)から、ハッシュ(#)部分を削除することで、ハッシュ(#)を含まないURLを生成(現時点では、まだ非推奨)
location オブジェクトの完全なURL(href)から、ハッシュ(#)部分を削除することで、ハッシュ(#)を含まないURLを生成には、次の JavaScript コードを使用します。JavaScript コード:
var new_url = location.href.replace(location.hash,"");
実際の URL を使用して、ハッシュ(#)が含まれないURLが生成で来たかどうかをチェックしてみましょう。
テストに使用するURL:
http://upa-pc.blogspot.jp/2015/02/pc-life-good-items.html?m=1#more
実行結果:
new_url : "http://upa-pc.blogspot.jp/2015/02/pc-life-good-items.html?m=1"
replace の詳細は以下のページをご覧ください。
String.prototype.replace() - JavaScript | MDN
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/String/replace
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/String/replace
(2015/2/13 追記)
なお、location.href を使用しているため、URL にベーシック認証の情報が含まれる場合があります。
詳しくは、以下の「URLにベーシック認証の情報が含まれている場合の問題について」を参照してください。
まとめ
以上の方法を使用することにより、ハッシュ(#)を含まないURLを生成することができました。
2 つの方法を紹介しましたが、特に理由がないのなら、複雑性の少ない「location オブジェクトの完全なURL(href)から、ハッシュ(#)部分を削除することで、ハッシュ(#)を含まないURLを生成」する方法が良いのではないかと思います。
(2015/2/13 追記)
現在は、「location オブジェクトの各プロパティを組み立てて、ハッシュ(#)を含まないURLを生成」を推奨します。
理由は、以下の「URLにベーシック認証の情報が含まれている場合の問題について」を参照してください。
(2015/2/13 追記)
現在は、「location オブジェクトの各プロパティを組み立てて、ハッシュ(#)を含まないURLを生成」を推奨します。
理由は、以下の「URLにベーシック認証の情報が含まれている場合の問題について」を参照してください。
「location オブジェクトの各プロパティを組み立てて、ハッシュ(#)を含まないURLを生成」では、URL を生成するために、プログラムの要素として変数が 4 つ、定数が 1 つ、演算子が 4 つの計 9 つ必要です。
一方、「location オブジェクトの完全なURL(href)から、ハッシュ(#)部分を削除することで、ハッシュ(#)を含まないURLを生成」では、変数が 2 つ、定数が 1 つ、メソッドが 1 つのの計 4 つで済みます。
この、ハッシュ(#)を含まない現在のページのURLを取得する JavaScript コードを利用する場合には、そのような点に注意しつつ、活用してみてください。
URLにベーシック認証の情報が含まれている場合の問題について (2015/2/13 追記)
「location オブジェクトの完全なURL(href)から、ハッシュ(#)部分を削除することで、ハッシュ(#)を含まないURLを生成」では、location.href の認証情報が含まれるケースがあります。
また、ベーシック認証の情報を含んだ URL を location.href で取得した場合に、一部の古いブラウザでは、セキュリティの問題(脆弱性)につながりかねない動作があります。
そのため、ベーシック認証の情報を含んだ URL を location.href で取得した場合に、問題のある動作を起こす古いブラウザがインターネット上から無くなるまでは、「location オブジェクトの各プロパティを組み立てて、ハッシュ(#)を含まないURLを生成」を使用するのが良さそうです。
詳しい情報は以下のページを参照してください。
JavaScript:location.hrefの注意点 - URLのドメイン前にベーシック認証が埋め込める、そして脆弱性
http://upa-pc.blogspot.com/2015/02/javascript-location-href-url-basic-trouble.html
また、ベーシック認証の情報を含んだ URL を location.href で取得した場合に、一部の古いブラウザでは、セキュリティの問題(脆弱性)につながりかねない動作があります。
そのため、ベーシック認証の情報を含んだ URL を location.href で取得した場合に、問題のある動作を起こす古いブラウザがインターネット上から無くなるまでは、「location オブジェクトの各プロパティを組み立てて、ハッシュ(#)を含まないURLを生成」を使用するのが良さそうです。
詳しい情報は以下のページを参照してください。
JavaScript:location.hrefの注意点 - URLのドメイン前にベーシック認証が埋め込める、そして脆弱性
http://upa-pc.blogspot.com/2015/02/javascript-location-href-url-basic-trouble.html
そのほかの手段
正規表現によるハッシュ(#)以降の削除
文字列の正規表現による置換により、URLのハッシュ(#)以降を取り除いた文字列を取得する方法もあります。
JavaScript:URLのハッシュ(#)以降を削除する - Dr.ウーパのコンピュータ備忘録
http://upa-pc.blogspot.jp/2014/05/javascripturl.html
http://upa-pc.blogspot.jp/2014/05/javascripturl.html
この方法の場合、URL が location オブジェクトに収められていなくても使えるため、汎用的に使用できます。
link タグの canonical から正規化した URL を取得
自分自身が所有するWebサイトのページであれば、すべてのページに正規化したそのページの URL を記載しておき、その値を現在のページの URL として JavaScript で取得するという手段もあります。
canonical属性とは/link rel="canonical"によるURL正規化タグ——SEOにとって非常に重要な進歩(前編) | Moz - SEOとインバウンドマーケティングの実践情報 | Web担当者Forum
http://web-tan.forum.impressrd.jp/e/2009/03/05/5112
正規 URL を使用する - ウェブマスター ツール ヘルプ
https://support.google.com/webmasters/answer/139066?hl=ja
http://web-tan.forum.impressrd.jp/e/2009/03/05/5112
正規 URL を使用する - ウェブマスター ツール ヘルプ
https://support.google.com/webmasters/answer/139066?hl=ja
一般的に、正規化した URL には ハッシュ(#) は含まないものであり、静的に Web ページに埋め込まれているか、Web サーバ側で正規化した URL が埋め込まれるため、現在の Web ページの URL を location から取得するよりも、手軽で安全です。
(危険な canonical の URL が埋め込まれるようであれば、それはサーバ側の問題です。)
(万が一、クライアント側の JavaScript で canonical を動的に追加しているような場合には、その生成方法が安全なものか確認する必要があります。)
なお、第三者の Web ページでは、正規化した URL に意図したものか、意図したものでないかにかかわらず、問題のある情報が含まれる可能性があるため、第三者の Web ページのlink タグの canonical の href 属性の値を使用する場合には、その値がセキュリティ上安全なものかチェックして使用する必要があります。
特に、URL のハッシュ(#)やクエリ文字列(?)部には、第三者が(多少の制限はあるとはいえ)好きなように文字を設定できてしまいます。
そのため、location から取得した URL に対して、JavaScript によって何らかの処理を行う場合には、セキュリティ上の問題を引き起こさないように考慮する必要があります。
特に、それらの値をそのまま document.write で書き出したり、document.innerHTML に設定したりすることは非常に危険です。
その結果、Web ページにアクセスしたユーザの情報が盗まれたり、悪意のあるサイトへ誘導されたりといった危険性があります。
そのような考慮が無く、セキュリティ上の脆弱性のある Web ページを作ってしまった場合には、第三者が細工を施した URL をメールや、Web 上の掲示板などのページに張り付けることで、そのページにアクセスした人のブラウザで危険な動作をさせることが可能です。
location の値の使用目的に応じて、適切なセキュリティ対策を施してください。
(この辺りの話については、後日別の投稿で詳しく説明したいと思います。)
なお、第三者の Web ページでは、正規化した URL に意図したものか、意図したものでないかにかかわらず、問題のある情報が含まれる可能性があるため、第三者の Web ページのlink タグの canonical の href 属性の値を使用する場合には、その値がセキュリティ上安全なものかチェックして使用する必要があります。
location の値を扱う上での注意
URL には、Webページの制作者が予期していない文字列を渡される可能性があります。特に、URL のハッシュ(#)やクエリ文字列(?)部には、第三者が(多少の制限はあるとはいえ)好きなように文字を設定できてしまいます。
そのため、location から取得した URL に対して、JavaScript によって何らかの処理を行う場合には、セキュリティ上の問題を引き起こさないように考慮する必要があります。
特に、それらの値をそのまま document.write で書き出したり、document.innerHTML に設定したりすることは非常に危険です。
その結果、Web ページにアクセスしたユーザの情報が盗まれたり、悪意のあるサイトへ誘導されたりといった危険性があります。
そのような考慮が無く、セキュリティ上の脆弱性のある Web ページを作ってしまった場合には、第三者が細工を施した URL をメールや、Web 上の掲示板などのページに張り付けることで、そのページにアクセスした人のブラウザで危険な動作をさせることが可能です。
location の値の使用目的に応じて、適切なセキュリティ対策を施してください。
(この辺りの話については、後日別の投稿で詳しく説明したいと思います。)
コメントを投稿
コメント投稿機能について