私は純粋にJavaScriptでOAuth認証フローを開発しており、ユーザーにポップアップで「アクセス許可」ウィンドウを表示したいのですが、ブロックされます。
によって作成されたポップアップウィンドウ、window.open
またはwindow.showModalDialog
別のブラウザーのポップアップブロッカーによってブロックされないようにするにはどうすればよいですか?
私は純粋にJavaScriptでOAuth認証フローを開発しており、ユーザーにポップアップで「アクセス許可」ウィンドウを表示したいのですが、ブロックされます。
によって作成されたポップアップウィンドウ、window.open
またはwindow.showModalDialog
別のブラウザーのポップアップブロッカーによってブロックされないようにするにはどうすればよいですか?
回答:
一般的なルールは、直接のユーザーアクションwindow.open
によって呼び出されないJavaScriptから、または同様のものが呼び出された場合、ポップアップブロッカーが関与することです。つまり、ポップアップブロッカーにヒットすることなくボタンのクリックに応答して呼び出すことができますが、タイマーイベントに同じコードを配置すると、ブロックされます。呼び出しチェーンの深さも要因です。一部の古いブラウザーは、直接の呼び出し元のみを確認します。新しいブラウザーは、少し戻って、呼び出し元の呼び出し元がマウスクリックであったかどうかを確認できます。ポップアップブロッカーを避けるために、できるだけ浅くしてください。window.open
Jason Sebringの非常に便利なヒントと、あちこちで取り上げられていることに基づいて、私の場合に最適な解決策を見つけました。
JavaScriptスニペットを使用した疑似コード:
ユーザーアクションですぐに空白のポップアップを作成する
var importantStuff = window.open('', '_blank');
オプション:「待機中」の情報メッセージを追加します。例:
a)外部HTMLページ:上記の行を
var importantStuff = window.open('http://example.com/waiting.html', '_blank');
b)テキスト:上記の行の下に次の行を追加します。
importantStuff.document.write('Loading preview...');
準備ができたらコンテンツを入力します(たとえば、AJAX呼び出しが返されたとき)
importantStuff.location.href = 'http://shrib.com';
window.open
必要な追加オプションを使用して、への通話を充実させます。
私は実際にこのソリューションをmailtoリダイレクトに使用し、すべてのブラウザー(windows 7、Android)で動作します。この_blank
ビットは、mailtoリダイレクトがモバイルで機能するのに役立ちます。
あなたの経験?これを改善する方法はありますか?
Whatever it is you intend to do, there is a better way than a popup window
笑?奇妙な一般化。クライアントは、認証したページを開いたままにし、認証後の新しいサイト/ランディングページを新しいタブで開くことを望んでいます。はい、優れたユーザーエクスペリエンスについての私の考えではありません...しかしそれは妥当なようです
importantStuff.close
て新しいタブを閉じ、元のページに警告を表示します。
さらに、スイスミスターの投稿、私の場合、window.openは、ポップアップブロッカーをオンにするpromise内で起動されました。私の解決策は次のとおりです。
$scope.gotClick = function(){
var myNewTab = browserService.openNewTab();
someService.getUrl().then(
function(res){
browserService.updateTabLocation(res.url, myNewTab);
}
);
};
browserService:
this.openNewTab = function(){
var newTabWindow = $window.open();
return newTabWindow;
}
this.updateTabLocation = function(tabLocation, tab) {
if(!tabLocation){
tab.close();
}
tab.location.href = tabLocation;
}
これが、promise応答を使用してポップアップブロッカーを呼び出さずに新しいタブを開く方法です。
const tab = window.open(); observable.subscribe(dataUrl => tab.location.href = dataUrl);
.then
その時の答えを見ることはありませんでした、そしてそれが私がとても混乱した理由です:/ SRY ...
良い方法として、ポップアップがブロックされたかどうかをテストし、万が一に備えてアクションを実行することをお勧めします。window.openには戻り値があり、アクションが失敗した場合はその値がnullになる可能性があることを知っておく必要があります。たとえば、次のコードでは:
function pop(url,w,h) {
n=window.open(url,'_blank','toolbar=0,location=0,directories=0,status=1,menubar=0,titlebar=0,scrollbars=1,resizable=1,width='+w+',height='+h);
if(n==null) {
return true;
}
return false;
}
ポップアップがブロックされている場合、window.openはnullを返します。したがって、関数はfalseを返します。
例として、任意のリンクからこの関数を直接呼び出すことを想像してください。
target="_blank"
ポップアップが正常に開かれた場合、戻るfalse
とリンクアクションがブロックされます。ポップアップがブロックされている場合、戻るtrue
とデフォルトの動作(新しい_blankウィンドウを開く)が行われます。 。
<a href="http://whatever.com" target="_blank" onclick='return pop("http://whatever.com",300,200);' >
このようにすると、機能する場合はポップアップが表示され、機能しない場合は_blankウィンドウが表示されます。
ポップアップが開かない場合は、次のことができます。
http://code.google.com/p/google-api-javascript-client/wiki/Authentication
それが読むエリアを見てください:
認証の設定
クライアントのOAuth 2.0の実装では、ポップアップウィンドウを使用して、ユーザーにサインインし、アプリケーションを承認するように求めます。gapi.auth.authorizeへの最初の呼び出しは、ポップアップウィンドウを間接的に開くため、ポップアップブロッカーをトリガーする可能性があります。ポップアップブロッカーが認証呼び出しでトリガーされないようにするには、クライアントの読み込み時にgapi.auth.init(callback)を呼び出します。ライブラリが認証呼び出しを行う準備ができると、指定されたコールバックが実行されます。
上記の本当の答えに関連していると思いますが、即時応答がある場合、ポップアップアラームは作動しません。「gapi.auth.init」はそれを作っているので、APIはすぐに発生します。
実用的なアプリケーション
npmのノードパスポートと各プロバイダーのさまざまなパスポートパッケージを使用して、オープンソース認証マイクロサービスを作成しました。私はサードパーティに標準のリダイレクトアプローチを使用して、リダイレクトURLを返しました。これはプログラマティックだったので、ログイン/サインアップの場合や特定のページにリダイレクトするために別の場所を使用することができました。
私は複数の解決策を試しましたが、実際にすべてのブラウザで機能したのは彼だけです
let newTab = window.open();
newTab.location.href = url;
url
?割り当てられていません。
http://example.com
window.open()
プログラムで新しいウィンドウを開くことができず、必要に応じてその答えが選択肢の1つになることです。ではnewTab
、変数我々はへの参照を作成window.open()
し、後で私たちは、INSERT、それを呼び出すことができますurl
いくつかのブロブの私の場合のURLには、私たちの必要性、および新しいタブが入力されたURL上で開かれます。
コールバックが正常に返されない限り、新しいページを作成したくなかったので、ユーザーのクリックをシミュレートするためにこれを行いました。
function submitAndRedirect {
apiCall.then(({ redirect }) => {
const a = document.createElement('a');
a.href = redirect;
a.target = '_blank';
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
});
}
これを取り除く最も簡単な方法は、次のとおりです。
例:
<script>
function loadUrl(location)
{
this.document.location.href = location;
}</script>
<div onclick="loadUrl('company_page.jsp')">Abc</div>
これは私にとって非常にうまくいきました。乾杯