Ajax でポップアップブロックを回避する方法

この記事は最終更新日から 10年以上 が経過しています。

最近のブラウザでは、JavaScript からウィンドウを開こうとした際、 ポップアップブロックによってブロックされてしまうことがあります。 通常のユーザーによる操作であれば問題ないのですが、 Ajax と組み合わせた際にもブロックされてしまうのは困りものです。 回避策を調査しましたので、ここに書いておきます。 少々ハマってしまったのと、忘れてしまいそうな自分への備忘録です。 誰かのお役にたてれば幸いです。

やりたいこと

ユーザーが送信ボタンをクリックすると、フォームに入力された内容をサーバーに Ajax する。
サーバーから帰ってきた結果が OK ならウィンドウを開く。NG ならウィンドウは開かない。

ポップアップブロックの主な振る舞い

JavaScript からウィンドウを開く際、 ユーザーからの操作に関係がない場合はブロックし、 ユーザーからの操作に関係がある場合はブロックされません。

例えば、jQuery.ready や onload イベントなど、ページ読み込み時に自動でウィンドウを開いたりする場合は、 ユーザーの操作に関係が無いのでブロックされます。 この場合、onload イベント内で click イベントを実行させてもブロックされます。 しかし、ユーザーがボタンをクリックした際の onclick イベント等では、 ユーザーの操作なのでブロックされません。

では、ユーザーがボタンをクリックした際の onclick イベントで、Ajax(非同期通信)した場合はどうでしょう? この場合、リクエストを送信するプロセスはブロックされませんが、 レスポンスを受け取るプロセスはブロックされます。

JavaScript
$(function() {

	window.open(~);	// ここではブロックされる

	$('#hoge').on('click', function() {

		window.open(~);	// ここではブロックされない

		$.ajax({
			url: ~,
			success: function(data) {
				window.open(~);	// ここではブロックされる
			}
		});
	});
});

なぜなら、Ajax は非同期通信であり、レスポンスを受け取るプロセスが別のプロセスになってしまうからです。 その別プロセスはユーザーの操作とは関係がないためブロックされます。 良くできてますよね。

ブロックされてしまうパターン

  • jQuery.ready や onload イベント
  • Ajax (非同期通信)

ブロックされないパターン

  • ユーザーが操作して発生したイベント(onclick 等)

回避策

しかしながら、今回はブロックさせたくないのです。ではどうするか。 Ajax(非同期通信)により、ユーザーの操作と通信処理が分断され、ブロックされてしまうのであれば、 ユーザーの操作と通信処理を分断させなければ良いわけです。 非同期通信ではなく、同期通信を使います。

JavaScript
$(function() {

	window.open(~);	// ここではブロックされる

	$('#hoge').on('click', function() {

		window.open(~);	// ここではブロックされない

		$.ajax({
			url: ~,
			async: false,	// 非同期ではなく同期通信にする
			success: function(data) {
				window.open(~);	// ここではブロックされない
			}
		});
	});
});

jQuery では非同期も同期も同じ ajax というメソッドなので混乱しやすいですが、 async フラグを false にすることで同期通信になります。 同期通信なので通信が終わるまで待ち状態になってしまいますが、 それはつまりユーザーの操作と関係しているプロセスということですので、 ポップアップブロックを回避してウィンドウを開くことが可能です。

まとめ

Ajax(Asynchronous JavaScript + XML)ではなく、 Sjax(Synchronous JavaScript + XML)です。

参考サイト

関連記事

最近、ダイアログを表示した際にページのスクロールを無効化する方法を探していて、思ったより苦戦したのですが、良い方法を見つけたので、忘れないように備忘録としてメモしておきます。誰かのお役に立てば幸いです。スクロールイベントはキャンセルできないまず最初にパッと思いついたのが、onscroll イベントハンドラーの中で pr ...
Twitter の埋め込みタイムラインを簡単に遅延読み込みさせる方法を思いついたので、備忘録としてメモしておきます。例として、Twitter の埋め込みタイムラインを使用していますが、他のサービスの埋め込みパーツでも同じ方法が使えると思います。誰かの参考になれば幸いです。Twitter の埋め込みタイムラインの問題点一 ...
最近のWebアプリでは、JavaScript を使ってがりがり処理することが多いです。動的にパラメータを渡して処理させることも多いのですが、うまく渡す方法を知らない人が意外と多いみたいです。なのでまとめてみます。誰かのお役にたてれば幸いです。前提説明しやすくするために下記の環境を想定します。文書型(DOCTYPE)HT ...

記事検索

最新記事

人気記事

RSSフィード

お知らせ

フィードバック

要望などあれば、お気軽にどーぞ。 不具合やバグを発見した場合も、連絡をいただけると助かります。

匿名でフィードバックする
匿名でフィードバックする

要望などあれば、お気軽にどーぞ。 不具合やバグを発見した場合も、連絡をいただけると助かります。

なお、このフォームから入力された内容について、管理者から返信はできませんので注意してください。 もし、管理者からの返信が必要であれば、X(Twitter) もしくは、お問い合わせより、お願いします。

  • フィードバックの送信が完了しました。