ユーザーがブラウザの履歴に戻ることができるかどうかを確認する方法


回答:


119

短い答え:できません。

技術的には、プロパティをチェックする正確な方法があります。

history.previous

ただし、機能しません。これに関する問題は、ほとんどのブラウザでこれはセキュリティ違反と見なされ、通常は未定義を返すだけです。

history.length

他の人が提案したプロパティです...
しかし、履歴のどこにいるかを示すものはないため、長さは完全には機能しません。また、常に同じ番号で始まるとは限りません。たとえば、ランディングページが設定されていないブラウザは0から始まりますが、ランディングページを使用する別のブラウザは1から始まります。

代替テキスト

ほとんどの場合、以下を呼び出すリンクが追加されます。

history.back();

または

 history.go(-1);

戻ることができない場合は、リンクをクリックしても何も起こらないことが予想されます。


これは良い情報ですが、問題は解決しません。実際にはどのブラウザでも機能するコードを作成する必要があります。おそらく、最初に使用しているブラウザをチェックするコードです。
サンティアゴベンダビッド2017

5
私が言っているのは、明確な答えはないということです。あなたはそれぞれのアプローチの長所と短所を言っていますが、使用しているブラウザをチェックして条件付きで1つまたは他のコードを実行するスクリプトを取得する方法は言っていません。
サンティアゴベンダビッド2017

「これの問題はほとんどのブラウザでこれはセキュリティ違反と見なされることです」とはどういう意味ですか?別のスレッドの別のユーザーも、クライアントのブラウザ履歴を取得できることはセキュリティ違反であることを指摘しましたが、説明していません何故ですか。誰もがセキュリティの脅威とは何かの例を挙げられますか?
Kevin Chandra

Webサイトは、間接的な個人情報を含む可能性のあるユーザーの履歴を認識できないようにする必要があります。サイトはトラッキング/ Cookieを使用して、ユーザーがサイト自体で何をしているのかを知ることができますが、たとえば、私が使用している銀行、子供が通っている学校などを把握することは許可されません。したがって、ブラウザはそのプロパティへのアクセスを許可しません
McAden

84

チェックする別の方法があります-リファラーをチェックしてください。通常、最初のページには空のリファラーがあります...

if (document.referrer == "") {
    window.close()
} else {
    history.back()
}

2
プライバシー上の理由から、リファラーを非表示にすることができます。
Kornel 2012

11
ページがリンクで読み込まれず、アドレスバーにURLを入力するか、ブックマークを読み込むと、リファラーは常に空になります。ただし、このようなページには、ブラウザーのタブ/ウィンドウが以前に別のページをロードしたことがある場合は、必ず履歴があります。
ygoe 2012

1
しかし、マルチページWebサイト全体のナビゲーションに適用できるソリューションです
Dan

36
新しいウィンドウを強制するためにtarget = "_ blank"でウィンドウを開いた場合は機能しません。ブラウザの[戻る]ボタンは機能しませんが、document.referrerがあります
Mike_K

3
安全な(HTTPS)ページから安全でないページ(HTTP)にアクセスしている場合、これは機能しません。リファラーが削除されるためです。
Kevin Borders

54

私のコードでは、ブラウザが1ページ戻り、失敗した場合はフォールバックURLが読み込まれます。また、ハッシュタグの変更を検出します。

[戻る]ボタンが使用できなかった場合、フォールバックURLは500ミリ秒後に読み込まれるため、ブラウザには前のページを読み込むのに十分な時間があります。window.history.go(-1);jsスクリプトがまだ停止していないため、直後にフォールバックURLをロードすると、ブラウザーはフォールバックURLを使用します。

function historyBackWFallback(fallbackUrl) {
    fallbackUrl = fallbackUrl || '/';
    var prevPage = window.location.href;

    window.history.go(-1);

    setTimeout(function(){ 
        if (window.location.href == prevPage) {
            window.location.href = fallbackUrl; 
        }
    }, 500);
}

6
これは問題の核心、人がなぜ気にかけるのか、そして信頼できる方法で一貫してそれについて実際に何ができるのかを本当に釘付けにすると思います。
Chris Marisic

1
これは、戻るボタンのあるURLを取得してChromeの新しいタブに貼り付けるまで機能しました。戻るボタンをクリックすると、空のタブに送信されます。:(
karlingen

2
これがChromeのデフォルトの動作です。ページに「アクセスした」ためchrome://newtab、履歴に戻ることができます。
redelschaap 2017

遅いネットワーク接続では、かなり頻繁にフォールバックURLにアクセスするため、これには注意してください。
cameck

14

ここに私がそれをした方法があります。

「beforeunload」イベントを使用してブール値を設定しました。次に、「beforeunload」が起動したかどうかを監視するタイムアウトを設定しました。

var $window = $(window),
    $trigger = $('.select_your_link'),
    fallback = 'your_fallback_url';
    hasHistory = false;

$window.on('beforeunload', function(){
    hasHistory = true;
});

$trigger.on('click', function(){

    window.history.go(-1);

    setTimeout(function(){
        if (!hasHistory){
            window.location.href = fallback;
        }
    }, 200);

    return false;
});

主要なブラウザで動作しているようです(FF、Chrome、IE11でテスト済み)。


1
これは、質問に対する断然最良の答えです。あなたは簡単に置き換えることができwindow.location.href = fallbackwindow.close()、それがあまりにも動作します。
Vitani 2017

13

私のプロジェクトで使用するスニペットがあります:

function back(url) {
    if (history.length > 2) {
        // if history is not empty, go back:
        window.History.back();
    } else if (url) {
        // go to specified fallback url:
        window.History.replaceState(null, null, url);
    } else {
        // go home:
        window.History.replaceState(null, null, '/');
    }
}

参考:History.jsを使用してブラウザーの履歴を管理します。


なぜhistory.lengthを2と比較するのですか?

Chromeのスタートページはブラウザの履歴の最初のアイテムとしてカウントされるためです。


いくつかの可能性history.lengthとユーザーの行動があります:

  • ユーザーがブラウザーで新しい空のタブを開き、ページを実行します。history.length = 2無効にしたいback()ユーザーが空のタブに移動するため、この場合はします。
  • ユーザーが以前にどこかでリンクをクリックして、新しいタブでページを開きますhistory.length = 1もう一度無効にしますback()メソッドます。
  • そして最後に、ユーザーはいくつかのページをリロードした後、現在のページに到達しますhistory.length > 2そして今back()有効にすることができます。

注:ユーザーが外部Webサイトからリンクをクリックした後に現在のページにアクセスした場合は、ケースを省略します。target="_blank"

注2: document.referrerアドレスを入力してWebサイトを開くとき、およびWebサイトがajaxを使用してサブページをロードするときは空なので、最初のケースでこの値のチェックを中止しました。


このアプローチは私にとってはうまくいきました。フォールバックで使用するページの静的フォールバックバックリンクを実際に保存しています。
グレッグブラス

ただし、戻ると、history.lengthは変更されません。つまり、適切に機能しません
Ciprian Mocanu

残念ながらあなたは正しい。私はこのスニペットを「ワンステップバック」構造でのみ使用しています…
gregmatys

12

これはトリックを行うようです:

function goBackOrClose() {  

    window.history.back();
    window.close(); 

    //or if you are not interested in closing the window, do something else here
    //e.g. 
    theBrowserCantGoBack();

}

history.back()を呼び出し、次にwindow.close()を呼び出します。ブラウザが履歴に戻ることができる場合、次のステートメントに進むことができません。戻ることができない場合は、ウィンドウを閉じます。

ただし、URLを入力してページにアクセスした場合、Firefoxはスクリプトがウィンドウを閉じることを許可しないことに注意してください。


3
私はそれ以外の場合は、history.back()の実行後に、とにかく実行されます、私は次のステートメントを実行しようとする前に、数百ミリ秒程度の遅延でのsetTimeoutを使用しない限り動作しません。これを見つけた
ケン・フェーリング

私はそれを個人的に経験したことがありません、どのブラウザーでしたか?
xtrahelp.com 2014年

私は以下の答えでsetTimeout関数でうまく働いていました。例:setTimeout(function(){window.close()}、400);
ギルクリス2014

2
window.close()最近の多くのブラウザではセキュリティリスクと見なされています。いくつかはあなたにそれをさせません。
Rudi Kershaw 2015年

window.history.back();の後は何でもできます。window.close(); 例にすぎません
ハリザマン

10

に注意してください window.history.lengthエントリも含まれのでwindow.history.forward()

したがってwindow.history.length、1つ以上のエントリがある可能性がありますが、履歴バックエントリはありません。これは、発砲しても何も起こらないことを意味しますwindow.history.back()


9

戻るボタンが使用可能かどうかを直接確認することはできません。を見ることができますが、現在のhistory.length>0ページのにページがある場合も同様です。戻るボタンが使用できないことを確認できるのは、history.length===0

history.back()それでも不十分な場合は、電話をかけるだけで済みます。その後もページが読み込まれる場合は、[戻る]ボタンを使用できません。もちろん、それは、戻るボタン利用可能な場合、ページから移動したことを意味します。でナビゲーションをキャンセルすることは許可されていませんonunload。そのため、実際に起きているのを止めるためにできることは、から何かを返すことだけですonbeforeunload。これにより、大きな煩わしいプロンプトが表示されます。それはそれだけの価値はありません。

実際、歴史について何かをすることは、通常、本当に悪い考えです。履歴ナビゲーションはブラウザのクロム用であり、ウェブページ用ではありません。「戻る」リンクを追加すると、通常、ユーザーに混乱が生じます。


2
長さに関して-それでもすべてのブラウザではそうではありません。一部のブラウザーは、現在のページを履歴アイテムとしてカウントし、1から開始します。ブラウザーの検出を含める必要があります。
マクアデン2010

実はいつもと思っていました1!これ0は頭痛の種だったので、ブラウザは常に1以上で応答すると思いました。OperaとIEは別の考えを持っていることがわかりました。
bobince

1
「履歴ナビゲーションはWebページではなくブラウザのクロム用です」-同意
ブライアン

5

history.lengthユーザーが履歴に戻ることができるかどうかは表示されないため、役に立ちません。また、異なるブラウザーは初期値0または1を使用します-それはブラウザーに依存します。

$(window).on('beforeunload'有効な解決策はイベントを使用することですが、ページがajaxを介してロードされ、pushStateを使用してウィンドウの履歴を変更した場合に機能するかどうかはわかりません。

だから私は次の解決策を使いました:

var currentUrl = window.location.href;
window.history.back();
setTimeout(function(){
    // if location was not changed in 100 ms, then there is no history back
    if(currentUrl === window.location.href){
        // redirect to site root
        window.location.href = '/';
    }
}, 100);

私の場合、次のように機能します:function goBackOrTo(targetUrl){var currentUrl = window.location.href; window.history.go(-1); setTimeout(function(){//場所が800 msで変更されなかった場合、履歴はありませんif(currentUrl === window.location.href){//サイトのルートにリダイレクトwindow.location.href = targetUrl; }}、800); }
alfonx 2015

2

私は次のアプローチを思いつきました。これは、onbeforeunloadイベントを利用して、ブラウザーがページから離れ始めるかどうかを検出します。特定の期間内に実行されない場合は、フォールバックにリダイレクトされます。

var goBack = function goBack(fallback){
    var useFallback = true;

    window.addEventListener("beforeunload", function(){
      useFallback = false;
    });

    window.history.back();

    setTimeout(function(){
        if (useFallback){ window.location.href = fallback; }
    }, 100); 
}

この関数は、を使用して呼び出すことができますgoBack("fallback.example.org")


1
私はこれが一番好きで、windows.onbeforeunloadイベントリスナーに変更しただけなwindow.addEventListener("beforeunload", function (event) { useFallback = false; });ので、window.onbeforeunloadを上書きしません。
MiChAeLoKGB 2017

2

ここここの答えに基づいて構築します。より結論的な答えは、これが新しいタブの新しいページかどうかを確認することだと思います。

ページの履歴が複数ある場合は、現在のページの前のページに戻ることができます。そうでない場合、タブは新しく開かれたタブであり、新しいタブを作成する必要があります。

異なる点として、リンクされた回答に対してはreferrer、新しいタブにはリファラーがまだあるため、チェックはしていません。

if(1 < history.length) {
    history.back();
}
else {
    window.close();
}

1
ありがとうございました。あなたは私の日を救った:)。
Bijay Yadav

1

別のSOの答えから取られた別のほぼ完璧な解決策があります

if( (1 < history.length) && document.referrer ) {
    history.back();
}
else {
    // If you can't go back in history, you could perhaps close the window ?
    window.close();
}

誰かtarget="_blank"がそれを使用すると機能しないと報告しましたが、Chromeでは私にとっては機能するようです。


0

ブラウザには戻るボタンと進むボタンがあります。私はこの問題の解決策を考え出します。ただし、ブラウザの転送アクションに影響し、一部のブラウザでバグが発生します。

それはそのように機能します:ブラウザが新しいURLを開いた場合、開いたことがない場合、history.lengthは大きくなります。

ハッシュを次のように変更できます

  location.href = '#__transfer__' + new Date().getTime() 

表示されないURLを取得するには、history.lengthが実際の長さを取得します。

  var realHistoryLength = history.length - 1

しかし、それが常にうまくいくとは限らず、なぜ、特にいつURLがすぐに自動ジャンプするのかはわかりません。


0

私は解決策を見つけようとしていましたが、これは私が得ることができる最高の方法です(ただし、うまく機能し、ここでも私が見つけた最も簡単な解決策です)。

私の場合、[戻る]ボタンで履歴に戻りたいのですが、ユーザーが開いた最初のページがアプリのサブページである場合、メインページに戻ります。

解決策は、アプリが読み込まれるとすぐに、履歴の状態を置き換えるだけでした:

history.replaceState( {root: true}, '', window.location.pathname + window.location.hash)

この方法では、history.state.root戻る前に確認する必要があります。trueの場合、代わりに履歴を置き換えます。

if(history.state && history.state.root)
    history.replaceState( {root: true}, '', '/')
else
    history.back() 

他に良いユースケースはないと思います。アプリの外で履歴を確認したい場合は、たぶん良い考えではありません。
Maxwell sc

-1
var fallbackUrl = "home.php";
if(history.back() === undefined)
    window.location.href = fallbackUrl;

これはとても簡単に見えますか?!さまざまなブラウザでテストされていますか?
ベンクジ2016

Chromeでhistory.back()あるundefinedのみ、空のタブページ
gregmatys

-2

解決

'use strict';
function previousPage() {
  if (window.location.pathname.split('/').filter(({ length }) => length > 0).length > 0) {
    window.history.back();
  }
}

説明

window.location.pathname現在のURIが表示されます。たとえばhttps://domain/question/1234/i-have-a-problemを与えるでしょう/question/1234/i-have-a-problem。詳細については、window.locationに関するドキュメントを参照してください。

次に、を呼び出すとsplit()、そのURIのすべてのフラグメントが取得されます。したがって、前のURIを取得すると、のようになり["", "question", "1234", "i-have-a-problem"]ます。詳細については、String.prototype.split()に関するドキュメントを参照してください。

への呼び出しfilter()は、バックスラッシュによって生成された空の文字列を除外するためにここにあります。基本的に、長さが1(空でない文字列)より大きいフラグメントURIのみを返します。したがって、次のようなものになり["question", "1234", "i-have-a-question"]ます。これは次のように書くことができます:

'use strict';
window.location.pathname.split('/').filter(function(fragment) {
  return fragment.length > 0;
});

詳細については、Array.prototype.filter()およびDestructuring割り当てに関するドキュメントを参照してください。

これで、ユーザーがをオンhttps://domain/にしたまま戻った場合、ifステートメントはトリガーされず、window.history.back()メソッドもトリガーされないため、ユーザーは引き続きWebサイトにとどまります。このURLは以下と等価になる[]の長さを有し0、かつ0 > 0falseです。したがって、静かに失敗します。もちろん、何かをログに記録したり、必要に応じて別のアクションを実行したりできます。

'use strict';
function previousPage() {
  if (window.location.pathname.split('/').filter(({ length }) => length > 0).length > 0) {
    window.history.back();
  } else {
    alert('You cannot go back any further...');
  }
}

制限事項

もちろん、ブラウザがHistory APIをサポートしていない場合、このソリューションは機能しません。このソリューションを使用する前に、ドキュメントで詳細を確認してください。


-5

これが機能するかどうかは完全にはテストされていませんが、これを試してください:

<script type="text/javascript">

    function goBack() {
        history.back();
    }

    if (history.length > 0) { //if there is a history...
        document.getElementsByTagName('button')[].onclick="goBack()"; //assign function "goBack()" to all buttons onClick
    } else {
        die();
    }
</script>

そして、HTMLのどこかに:

<button value="Button1"> //These buttons have no action
<button value="Button2">

編集:

また、back機能をサポートしているブラウザーを調査し(すべてサポートされていると思います)、このページで見つけられ、完全に説明されている標準のJavaScriptブラウザー検出オブジェクトを使用します。次に、2つの異なるページを作成できます。1つは[戻る]ボタンと互換性のある「適切なブラウザ」用、もう1つは「悪いブラウザ」用で、ブラウザを更新するように指示します。


2
history.back関数です。history.length > 0それが戻ったかどうかを確認したいhistory.back()
pixl coder '27

3
また[]、NodeListでは意味がなく、イベントハンドラーに文字列を割り当てることはできません。
ボビンス

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.