Unikaj blokowania wyskakujących okienek przeglądarki

Rozwijam przepływ uwierzytelniania OAuth wyłącznie w JavaScript i chcę pokazać użytkownikowi okno" grant access " w popup, ale zostaje zablokowane.

Jak zapobiec blokowaniu wyskakujących okien utworzonych przez window.open LUB window.showModalDialog przez blokery wyskakujących okien różnych przeglądarek?

Author: Mark Amery, 2010-04-06

8 answers

Ogólna zasada jest taka, że blokery popup będą uruchamiane, jeśli {[0] } lub podobne jest wywoływane z javascript, który nie jest wywoływany przez direct user action. Oznacza to, że możesz wywołać window.open w odpowiedzi na kliknięcie przycisku bez uderzenia przez bloker wyskakujących okienek, ale jeśli umieścisz ten sam kod w zdarzeniu czasowym, zostanie on zablokowany. Głębokość łańcucha połączeń jest również czynnikiem - niektóre starsze przeglądarki patrzą tylko na natychmiastowego rozmówcy, nowsze przeglądarki mogą cofnąć się trochę, aby sprawdzić, czy rozmówca rozmówcy był kliknięcie myszką itp. Trzymaj go tak płytko, jak to tylko możliwe, aby uniknąć blokerów wyskakujących okienek.

 225
Author: dthorpe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-27 17:48:55

Dodatkowo w moim przypadku okno .open został uruchomiony wewnątrz obietnicy, która włączyła popup blocker, moim rozwiązaniem było: in angular:

$scope.gotClick = function(){

  var myNewTab = browserService.openNewTab();
  someService.getUrl().then(
    function(res){
        browserService.updateLocation(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;
}

W ten sposób można otworzyć nową kartę za pomocą odpowiedzi promise i nie wywoływać blokera wyskakujących okienek.

 16
Author: David,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-27 11:44:13

Jako dobra praktyka myślę, że jest to dobry pomysł, aby przetestować jeśli popup został zablokowany i podjąć działania w przypadku. Musisz znać to okno.open ma zwracaną wartość i ta wartość może być null, jeśli akcja nie powiodła się. Na przykład w następującym kodzie:

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;
}

Jeśli wyskakujące okienko jest zablokowane, window.open zwróci wartość null. Więc funkcja zwróci false.

Jako przykład, wyobraź sobie wywołanie tej funkcji bezpośrednio z dowolnego łącza with target="_blank": if the popup is successful otwarty, powrót false zablokuje działanie łącza, w przeciwnym razie, jeśli wyskakujące okienko jest zablokowane, zwrócenie true pozwoli na domyślne zachowanie (Otwórz nowy _blank okno) i dalej.

<a href="http://whatever.com" target="_blank" onclick='return pop("http://whatever.com",300,200);' >

W ten sposób będziesz miał wyskakujące okienko, jeśli to działa, i okno _blank, jeśli nie.

Jeśli wyskakujące okienko się nie otworzy, możesz:

  • otwórz puste okno jak w przykładzie i idź dalej
  • Na stronie znajduje się wiele plików tekstowych.]}
  • poinformuj użytkownika ("proszę na tej stronie można wyświetlać wyskakujące okienka.]}
  • otwórz puste okno, a następnie poinformuj użytkownika itd..
 14
Author: FrancescoMM,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-25 11:20:26

Z OAuth JavaScript API Google:

Http://code.google.com/p/google-api-javascript-client/wiki/Authentication

Zobacz obszar, w którym jest napisane:

Konfiguracja uwierzytelniania

Implementacja klienta OAuth 2.0 używa wyskakującego okna, aby poprosić Użytkownika o zalogowanie się i zatwierdzenie aplikacji. Pierwszy telefon do gapi.auth.autoryzacja może wywołać blokery wyskakujących okienek, ponieważ otwiera okno wyskakujące pośrednio. Aby zapobiec blokowaniu wyskakujących okienek wyzwalanie przy połączeniach auth, zadzwoń do gapi.auth.INIT (callback) podczas ładowania klienta. Dostarczone wywołanie zwrotne zostanie wykonane, gdy biblioteka będzie gotowa do wykonywania połączeń auth.

Domyślam się, że odnosi się to do prawdziwej odpowiedzi powyżej w jaki sposób wyjaśnia, jeśli istnieje Natychmiastowa odpowiedź, nie potknie się alarmu wyskakującego. "Gapi.auth.init " sprawia, że api dzieje się natychmiast.

Zastosowanie Praktyczne

Zrobiłem mikroserwis uwierzytelniania open source używając node paszport na npm i różne pakiety paszportowe dla każdego dostawcy. Użyłem standardowego podejścia przekierowania do strony 3rd, dając mu adres URL przekierowania, do którego można wrócić. To było programowe, więc mogłem mieć różne miejsca do przekierowania z powrotem do if login/rejestracja i na poszczególnych stronach.

Github.com/sebringj/athu

Passportjs.org

 8
Author: Jason Sebring,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-15 04:58:11

Nie chciałem tworzyć nowej strony, chyba że wywołanie zwrotne wróciło pomyślnie, więc zrobiłem to, aby symulować użytkownik kliknął:

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);
  });
}
 0
Author: user3479425,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-12 19:28:36

Próbowałem wielu rozwiązań, ale jego jest jedynym, który naprawdę działał dla mnie we wszystkich przeglądarkach

let newTab = window.open(); newTab.location.href = url;

 -2
Author: pomobc,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-02 22:02:55

Najprostszym sposobem na pozbycie się tego jest, co działało dla mnie bardzo dobrze -

  1. nie używaj dokumentu.open().
  2. zamiast tego użyj tego.dokument.miejsce.href = location; gdzie location jest adresem URL do załadowania

Ex:

<script>
function loadUrl(location)
{
this.document.location.href = location;
}</script>

<div onclick="loadUrl('company_page.jsp')">Abc</div>
To działa bardzo dobrze. Cheers
 -4
Author: Pramod Shetty,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-31 00:00:20