3

私のコンテンツ (JS を含む) は、仲介者 (ディストリビューター) の iFrame にカプセル化された iFrame で提供され、パブリッシャーによって Web サイトに読み込まれます。3 つのフレームはすべて、異なるドメイン (クロスドメイン) から提供されます。

トップ フレームの URL (Web サイトの URL) を iFrame 内から特定する必要があります。しかし、私は iFrame でしか JS を実行できません。仲介者または Web サイトの発行者は無関係です。スクリプトを配置したり、中間の iFrame または Web サイトのソースコードを変更したりするように依頼することはできません。

私の質問は、次のような答えでこれに似ています:

var parentUrl = document.referrer;

ただし、現在は 2 つのネストされた iFrame があるため、document.referrer を要求すると、発行者の Web サイトではなく、仲介者の iFrame の URL のみが取得されます。

では、少なくとも一部の最近のブラウザでは、ネストされた複数のクロスドメイン iFrame 内でトップ ウィンドウの URL フォームを特定することは可能でしょうか?

4

1 に答える 1

4

Chrome と Opera では (複数の入れ子になったクロスドメイン iframe で) ドメインを取得するステルスな方法がありますが、他のブラウザーでは不可能です。

「window.location.ancestorOrigins」プロパティを使用する必要があります。これは、広告の世界ではちょっとした企業秘密のようです。彼らは私がそれを投稿することを好まないかもしれませんが、他の人に役立つ情報を共有し、理想的には十分に文書化され維持されているコードの例を共有することが重要だと思います.

したがって、共有するコードのスニペットを以下に作成しました。コードまたはコメントを改善できると思われる場合は、遠慮なく Github の要点を編集して、さらに改善できるようにしてください。

要点: https://gist.github.com/ocundale/281f98a36a05c183ff3f.js

コード (ES2015):

// return topmost browser window of current window & boolean to say if cross-domain exception occurred
const getClosestTop = () => {
    let oFrame  = window,
        bException = false;

    try {
        while (oFrame.parent.document !== oFrame.document) {
            if (oFrame.parent.document) {
                oFrame = oFrame.parent;
            } else {
                //chrome/ff set exception here
                bException = true;
                break;
            }
        }
    } catch(e){
        // Safari needs try/catch so sets exception here
        bException = true;
    }

    return {
        'topFrame': oFrame,
        'err': bException
    };
};

// get best page URL using info from getClosestTop
const getBestPageUrl = ({err:crossDomainError, topFrame}) => {
    let sBestPageUrl = '';

    if (!crossDomainError) {
        // easy case- we can get top frame location
        sBestPageUrl = topFrame.location.href;
    } else {
        try {
            try {
                // If friendly iframe
                sBestPageUrl = window.top.location.href;
            } catch (e) {
                //If chrome use ancestor origin array
                let aOrigins = window.location.ancestorOrigins;
                //Get last origin which is top-domain (chrome only):
                sBestPageUrl = aOrigins[aOrigins.length - 1];
            }
        } catch (e) {
            sBestPageUrl = topFrame.document.referrer;
        }
    }

    return sBestPageUrl;
};

// To get page URL, simply run following within an iframe on the page:
const TOPFRAMEOBJ = getClosestTop();
const PAGE_URL = getBestPageUrl(TOPFRAMEOBJ);

標準 ES5 のコードが必要な場合は、私に連絡するか、オンラインのコンバーターで実行してください。

于 2016-01-20T12:34:37.600 に答える