3

Flash ゲームを含むウィンドウを起動し、Chrome のポップアップ ブロッカーがそれを抑制すると、ユーザーにはゲームの音楽が聞こえますが、何も表示されません。これは、Chrome がウィンドウをブロックしないためです。それはそれを隠すだけです。

Chrome はページを読み込んでファビコンとページ タイトルを取得し、それをポップアップ ブロッカー ダイアログ (アドレス バーのアイコンをクリックすると表示される) に表示できるようにします。しかし、彼らは窓を閉めません。プラグインが実行され、スクリプトがオープナーにコールバックできます - 通常のウィンドウのようですが、見えません。(さて、マルウェア開発者の皆さん、よだれを垂らすのはやめてください。)

Chrome は <head> タグのコンテンツを解析して、実際にページをロードしなくても <title> および favicon <link/> タグを取得できます。アイコン/タイトルを取得した後、非表示のウィンドウを閉じることができます。アイコン/タイトルの代わりに URL を表示することもできます。代わりに、バグは2008年以来悪化し続けています...

http://code.google.com/p/chromium/issues/detail?id=3477

http://code.google.com/p/chromium/issues/detail?id=38458

とにかく、問題は次のとおりです。これがいつ発生したかを検出できますか? window.chrome JavaScript オブジェクトには、ウィンドウがこの非表示の状態にあることを示す何かがあるので、ウィンドウを閉じるか、フラッシュを削除できますか?

__

Prusseの答えに基づいて、これが私が最終的に得たものです...

function isPopupZombie(popWindow, delay) {
    /// <summary>Attempts to detect zombie window "blocked" (hidden) by Chrome (v.8-12, maybe more)</summary>
    /// <param name="popWindow">The popup window object</param>
    /// <param name="delay">Optional delay in ms; Not necessary when called via other delayed event/function</param>
    if (window.chrome && typeof(popWindow) == 'object') {
        if (delay && !isNaN(parseInt(delay)) && delay > 0) {
            window.setTimeout(function () {
                isPopupZombie(popWindow, 0);
            }, delay);
        } else if (typeof(popWindow.opener) == 'object') {
            var w = (popWindow.innerWidth && popWindow.innerWidth > 0) ? popWindow.innerWidth : popWindow.outerWidth;
            var h = (popWindow.innerHeight && popWindow.innerHeight > 0) ? popWindow.innerHeight : popWindow.outerHeight;
            //console.log('_isPopupZombie: ' + w + ' x ' + h);
            return (w === 0 && h === 0);
        }
    }
    return false;
}

function handlePopupZombie(zombieWindow, notify, callback) {
    /// <summary>Tries to close the zombie or alert about Chrome FAIL</summary>
    /// <param name="zombieWindow">Popup window object known to be a hidden but unblocked popup</param>
    /// <param name="notify">true to notify user of hidden window, false to close zombieWindow</param>
    /// <param name="callback">optional function to call, with single argument for zombieWindow</param>
    if (window.chrome && zombieWindow) {
        if (notify === true) {
            // callback or alert
            if (typeof(callback) == 'function') {
                callback(zombieWindow);
            } else if (zombieWindow.opener) {
                zombieWindow.opener.alert("Your popup blocker has hidden a popup window instead of blocking it.\n\nPlease use the icon in the address bar to open the hidden window.");
            }
        } else {
            // try to kill the zombie
            if (zombieWindow.opener && zombieWindow.opener.console) zombieWindow.opener.console.log('Closing zombie window');
            // after close, blocker icon is in address bar, but favicon/title are not in dialog
            zombieWindow.close();
            // optional callback
            if (typeof(callback) == 'function') callback(zombieWindow);
        }
    }
}

だから私は次のようなことができます...

var popup = window.open(...);

if (typeof(popup) == 'undefined') {
    // handle it
} else if (popup && popup.closed) {
    // handle it
} else if (isPopupZombie(popup, 100)) {
    console.log('popup zombie!');
    handlePopupZombie(popup, true);
} else {
    console.log('no zombies, this is regular ordinary popup code time!');
}
4

1 に答える 1

3

innerWidth、innerHeight、outerWidth、outerHeight を確認してみてください。クロムをブロックすると、それらが 0 になるように見えます。

window.addEventListener('load', function(){
    var w = window.open('');
    setTimeout(function(){
        if ((w.outerWidth === 0) && (w.outerHeight === 0)){
            alert('blocked!');
        }
        w = null;
    }, 25);
}, false);

クロムの場合、すべての新しいウィンドウは (0,0) サイズで作成され、しばらくしてから適切なサイズになるため、0 の遅延は機能しません。

于 2011-06-30T20:37:31.327 に答える