7

コンテンツ スクリプト ベースの Chrome 拡張機能があります。コンテンツ スクリプトのポップアップ ウィンドウからサインイン プロセスを開始します。

以下のコードを使用してポップアップ ウィンドウを開き、閉じられるまで待ちます。

ただし、window.openメソッドから「未定義」を取得します。なぜこれが起こるのか誰か知っていますか?

loginwin以下のコードにありundefinedますが、ポップアップウィンドウは指定されlogin_urlた . 以下のコードは、コンテンツ スクリプトから呼び出されます。

var loginWin = window.open(login_url, 'LoginWindow', "width=655,height=490");
console.log(loginWin);
// Check every 100 ms if the popup is closed.
var finishedInterval = setInterval(function() {
    console.log('checking if loginWin closed');
    if (loginWin.closed) {
        clearInterval(finishedInterval);
        console.log('popup is now closed');
        Backbone.history.navigate('index', true);
    }
}, 1000);
4

2 に答える 2

6

注: この回答は廃止されました。window.open()Chrome 拡張機能では、null(ポップアップがブロックされている場合) またはwindowオブジェクトのいずれかが常に返されます。以下の情報は、非常に古い (2012) バージョンの Chrome にのみ適用されます。


windowコンテンツ スクリプトは、ページのグローバルオブジェクトにアクセスできません。コンテンツ スクリプトの場合、以下が適用されます。

  • 変数は、windowページのグローバル オブジェクトを参照していません。代わりに、ページ上の「レイヤー」という新しいコンテキストを参照します。ページの DOM は完全にアクセス可能です。#実行環境

で構成されるドキュメントが与えられた場合   <iframe id="frameName" src="http://domain/"></iframe>:

  • フレームのコンテンツへのアクセスは、ページの同一オリジン ポリシーによって制限されます。拡張機能のアクセス許可は、ポリシーを緩和しません。
  • frames[0]frames['frameName']、(通常はフレームに含まれるグローバルwindowオブジェクトを参照) はundefinedです。
  • var iframe = document.getElementById('frameName');
    • iframe.contentDocumentdocumentコンテンツ スクリプトはページの DOM にアクセスできるため、含まれているフレームのオブジェクトを返します。このプロパティはnull、Same origin ポリシーが適用される場合です。
    • iframe.contentDocument.defaultView(windowドキュメントに関連付けられたオブジェクトを参照) はundefinedです。
    • iframe.contentWindow未定義 です。

ご覧のとおり、はインスタンスwindow.open()を返しません(なども返しません)。Windowwindow.opener


代替案

  • ページにコードを挿入して、ページのコンテキストで実行されるようにします。注: この方法は、操作しているページが信頼できる場合にのみ使用してください。挿入されたスクリプトとコンテンツ スクリプトの間で通信するには、次を使用できます。

    var login_url = 'http://example.com/';
    var event_name = 'robwuniq' + Math.random().toString(16); // Unique name
    document.addEventListener(event_name, function localName() {
        document.removeEventListener(event_name, localName); // Clean-up
        // Your logic:
        Backbone.history.navigate('index', true);
    });
    // Method 2b: Inject code which runs in the context of the page
    var actualCode = '(' + function(login_url, event_name) {
        var loginWin = window.open(login_url, 'LoginWindow', "width=655,height=490");
        console.log(loginWin);
        // Check every 100 ms if the popup is closed.
        var finishedInterval = setInterval(function() {
            console.log('checking if loginWin closed');
            if (loginWin.closed) {
                clearInterval(finishedInterval);
                console.log('popup is now closed');
                // Notify content script
                var event = document.createEvent('Events');
                event.initEvent(event_name, false, false);
                document.dispatchEvent(event);
            }
        }, 1000);
    } + ')(' + JSON.stringify(login_url+'') + ', "' + event_name + '")';
    var script = document.createElement('script');
    script.textContent = actualCode;
    (document.head||document.documentElement).appendChild(script);
    script.parentNode.removeChild(script);
    
  • を使用して、バックグラウンド ページからウィンドウを起動しますwindow.open()windowこれは、信頼できるプロパティを持つオブジェクトを返しclosedます。通信フローの詳細については、次の箇条書きを参照してください。

  • コンテンツ スクリプトから、メッセージ背景ページに渡します。バックグラウンド ページでは、 を使用chrome.windows.createしてウィンドウを開きます。chrome.tabs.onRemovedコールバックで、 and/orchrome.tabs.onUpdatedイベントを割り当てます。sendResponseこれらのイベント リスナーがトリガーされると、それらは自身を削除し、 の関数を使用して元の呼び出し元 (コンテンツ スクリプト) に通知する必要がありchrome.extension.onMessageます。
于 2012-08-05T10:10:37.943 に答える