jQuery / Javascriptを使用してフォームの更新を防止する


92

ユーザーが自分のページにアクセスしたら、ユーザーにページを更新させたくありません。

  1. いつでも、ユーザーF5は上部のボタンを押すか、更新します。彼は言ってアラートを取得する必要があります

    ページを更新できません。

  2. また、ユーザーが新しいタブを開き、前のタブで同じURLにアクセスしようとすると、アラートが表示されます

    2つのタブで同じページを開くことはできません

とにかく、JavaScriptまたはjQueryを使用してこれを行うことができますか?ポイント1は本当に重要です。


Broadcast Channel API(developer.mozilla.org/en-US/docs/Web/API/Broadcast_Channel_API)を使用して検出し、メッセージを送信してタブ間で通信できます。THUS、これを使用して、同じURLを持つ複数のタブを検出し、他のタブをブロックできます。
aXuser264

回答:


191

#1はを介して実装できますwindow.onbeforeunload

例えば:

<script type="text/javascript">
    window.onbeforeunload = function() {
        return "Dude, are you sure you want to leave? Think of the kittens!";
    }
</script>

ユーザーにはメッセージが表示され、ページに留まるか続行するかのオプションが表示されます。これはより一般的になっています。Stack Overflowは、投稿を入力しているときにページから移動しようとすると、これを行います。ユーザーがリロードするのを完全に止めることはできませんが、そうした場合、本当に恐ろしいサウンドにすることができます。

#2は多かれ少なかれ不可能です。セッションとユーザーログインを追跡したとしても、2番目のタブが正しく検出されたことを保証することはできません。たとえば、ウィンドウを1つ開いてから閉じます。新しいウィンドウが開きます。私は最初のタブをすでに閉じていたとしても、それを2番目のタブとして検出する可能性があります。これで、ユーザーは最初のウィンドウを閉じたためにアクセスできなくなり、2番目のウィンドウは拒否したためにアクセスできなくなりました。

実際、私の銀行のオンラインシステムは#2に真剣に取り組んでおり、上記の状況は常に発生しています。私は通常、銀行システムを再び使用する前に、サーバー側のセッションが期限切れになるまで待たなければなりません。


1
Operaブラウザのバージョンではonbeforeunloadイベントは利用できないことに注意してください。
WillyCornbread 2010

1
ユーザーがページに留まることを選択した場合に何かを行う方法はありますか?
riship89

5
クロスブラウザの互換性とライブラリの問題を防ぐために、代わりにwindow.addEventListener(developer.mozilla.org/en-US/docs/Web/Events/beforeunloadを参照)を使用する必要がありますが、私にとってはトリックでした。
JulienBérubé2014年

私はこの質問は古いです知っているが、彼らがいる場合、実際に複数のセッションを防ぐために望んでいた、彼らはWebSocketをを使用することができますか?
メーガン、2015

1
@Sean-うん...あなたが本当に複数のセッションを防ぎたいなら。WebSocketは、ステートフルな双方向通信を実行できます。WebSocketが接続されている間、クライアントは(おそらく)突然他の誰かになることはないので、そのユーザーにトークンを割り当て、ソケットが閉じたらトークンをクリアできるはずです。しかし、ユーザーエージェントの予想される動作をハッキングしているため、おそらく悪いUXです。このようなことが適切なケースは非常に少ないと思います(おそらくオンラインゲーム-2 つのレベル37の死の爪としてログインするのを防ぐために...)。
Seth

35

ユーザーが更新するのを防ぐことはできませんし、実際に試してはいけません。このソリューションが必要な理由に戻る必要があります。ここでの根本的な問題は何ですか。そこから始めて、問題を解決するための別の方法を見つけてください。おそらく、これを実行する必要があると思う理由について詳しく説明していると思いますが、そうした解決策を見つけるのに役立ちます。

基本的なブラウザ機能を壊すことは決して良い考えではありません。インターネットの99.999999999%以上がF5で動作し、更新されます。これは、ユーザーの期待であり、壊してはいけません。


問題は、ページがSiebelアプリケーションであることです。また、ユーザーがセッション中にいるときに更新を押すと、新しいセッションが作成され、アプリがクラッシュします。したがって、ユーザーが更新できないようにする必要があります。
pankaj 2010

20
@pankaj-ユーザーがタブ間でセッションを共有できるように、アプリケーションサイトやCookieなどで修正する必要があります。
Nick Craver

9
どこから来たのかわかりません。ダーティなフォームがある場合、インターネット上の無数のサイトがブラウザの更新を妨げ、変更が失われる可能性があることを警告します。これが「ブラウザの基本機能を壊す」理由がわかりません。
Siraris 2018年

1
@シラリス:その通り。さらに、ユーザーがプライベートネットワークに接続していなくても使用できるはずのプライベートアプリケーションを作成しています。したがって、オフラインで使用するためにすべてをブラウザのストレージに保存しますが、彼がページをリロードすると、アプリケーション全体が失われます。あまり「普通」ではないかもしれませんが、この現代のITの世界ではますます一般的になるでしょう。
cslotty

16

F5キーを無効にすることはお勧めできませんが、以下のようにJQueryで無効にすることができます。

<script type="text/javascript">
function disableF5(e) { if ((e.which || e.keyCode) == 116 || (e.which || e.keyCode) == 82) e.preventDefault(); };

$(document).ready(function(){
     $(document).on("keydown", disableF5);
});
</script>

これが役立つことを願っています!


27
CMD + RのOSXについてはどうですか?または、押すボタンがあるモバイルですか?私はこれを解決策とは考えていません
ItalyPaleAle 2015

14

CGIのかつての時代には、さまざまなバックエンドアクションをトリガーする多くのフォームがありました。グループへのテキスト通知、印刷ジョブ、データのファーミングなど。

ユーザーが「しばらくお待ちください...時間がかかる可能性のある巨大なジョブを実行しています。」というページを表示していた場合。彼らはREFRESHをヒットする可能性が高く、これは悪いことです!

どうして?それはより遅いジョブをトリガーし、最終的にはすべてを妨げてしまうからです。

ソリューション?彼らに彼らの形をさせる。彼らがフォームを送信したら...ジョブを開始してから、待機するように指示する別のページに誘導します。

真ん中のページが、ジョブを開始するために必要なフォームデータを実際に保持していた場所。ただし、WAITページにはJavaScriptの履歴破棄が含まれています。そのため、待機ページは必要なだけRELOADでき、WAITページにはWAIT自体に必要なフォームデータのみが含まれているため、元のジョブがバックグラウンドで開始されることはありません。

それが理にかなっていると思います。

履歴破棄機能により、[戻る]をクリックしてから更新することもできませんでした。

それは非常にシームレスで、非営利団体が解雇されるまでの何年にもわたって優れた働きをしました。

例:フォームエントリ-すべての情報を収集し、送信すると、バックエンドジョブがトリガーされます。

フォームエントリからの応答-静的待機ページへのリダイレクトや別のフォーム(待機ページ)へのPOST / GETを実行するHTMLを返します。

WAIT PAGE-待機ページに関連するFORMデータと、最新の履歴を破棄するJavaScriptのみが含まれます。(-1 OR -2)のように、最新のページのみを破棄しますが、元のFORMエントリページに戻ることができます。

ユーザーがWAITページに移動すると、必要に応じてREFRESHをクリックでき、バックエンドで元のFORMジョブを生成することはありません。代わりに、WAITページはMETA時限更新自体を採用する必要があるため、ジョブのステータスを常に確認できます。彼らの仕事が完了すると、彼らはあなたが望むどこにでも待機ページから離れてリダイレクトされます。

手動でREFRESHを実行する場合...ジョブのステータスのチェックを1つ追加するだけです。

お役に立てば幸いです。幸運を。


2
この驚くべき有益な答えに対する十分な信用を得られませんでした。ありがとうございました!!
ShiningLight


2

数値(2)は、ユーザーが従事しているセッションごとにカスタムハートビートを使用したソケット実装(websocket、socket.ioなど)を使用することで可能になります。ユーザーが別のウィンドウを開こうとすると、JavaScriptハンドラーチェックが行われます。問題がない場合はサーバーで確認し、エラーメッセージで応答します。

ただし、より良い解決策は、Googleドキュメントのように、可能であれば2つのセッションを同期させることです。


2

BroadcastAPIを使用して問題#2を解決できるようになりました

現在、Chrome、Firefox、Operaでのみご利用いただけます。

var bc = new BroadcastChannel('test_channel');

bc.onmessage = function (ev) { 
    if(ev.data && ev.data.url===window.location.href){
       alert('You cannot open the same page in 2 tabs');
    }
}

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