Javascript, трек iframe, перенаправляющий верхнее окно - программирование
Подтвердить что ты не робот

Javascript, трек iframe, перенаправляющий верхнее окно

Поскольку не существует способа предотвратить перенаправление iframe верхнего кадра, кроме песочницы, которая предотвращает другие функции, необходимые для отслеживания видимости, я хотел бы отслеживать перенаправления. Поскольку один сайт может иметь более одного iframe, он может быть любым из них.

Есть ли способ отслеживать/выяснить, какой из них (конкретный iframe) вызвал перенаправление верхнего кадра?

Вот песочница (используйте консоль браузера и включите журнал сохранения):

Edit 3v50wqxz66

Обратите внимание, что содержимое iframe обычно является кросс-доменом. Для удобства использования в сандоксах.

4b9b3361

Ответ 1

Мы можем получить доступ к содержимому iframe с помощью somethig, например iframe.contentWindow.document но это возможно, если мы соблюдаем политику одинакового происхождения.

Другой подход может заключаться в создании заголовка Content-Security-Policy например:

<meta http-equiv="Content-Security-Policy" content="frame-src http://example.com">

Этот заголовок на родительской странице предотвращает загрузку сайтов, отличных от http://example.com, в фреймах. Существует также способ сообщить о поведении отправителя сообщения, но, к сожалению, не может быть установлен с <meta> (только он сервер). При таком подходе мы должны выполнить белый список, поэтому я думаю, что, возможно, это не полезно в этом случае. Но, если белый список указан в первый раз, можно установить все доступные сайты, поэтому при перенаправлении iframe браузер откажется его загрузить.

Если это не так, как в случае с одним и тем же происхождением и с возможностью выполнения белого списка, то я думаю, что лучше, чем мы можем сделать, это вызывать событие iframe onunload, к сожалению это событие будет onunload также, когда страница iframe перезагружает не только перенаправление. Я думаю, что это самый близкий подход. Для этого этот код работает.

var srcs = ["iframe2.html","iframe.html","iframe2.html"];


        for (let i = 0; i < srcs.length; i++) {
            var iframe = document.createElement('iframe'); 
                iframe.src = srcs[i]; 
                iframe.name = "i"+i; 
                document.body.appendChild(iframe);
                window["i"+i].onunload = function(){console.log("change "+i)}
        }

Конечно, onunload запускается в первый раз, когда все фреймы загружаются, поэтому перенаправления 2-го 3-го и так далее. Но мы можем исключить этот первый случай.

Здесь полный пример https://codesandbox.io/s/o16yk7mqy, я создал iframe3.html, который не обновляет ни перезагрузку, чтобы четко показать эту точку. Также я создал простой список перенаправления или перезагрузки iframes.

ОБНОВЛЕНИЕ Как я понимаю сейчас, вы хотите установить iframes с свойством песочницы и белый список всего, что вы хотите, но без allow-top-navigation, что-то вроде:

<iframe src="iframe.html" sandbox="allow-script allow-forms allow-popups allow-pointer-lock allow-same-origin"></iframe>
  • Этот пример не позволяет allow-top-navigation https://codesandbox.io/s/lpmv6wr6y9
  • Этот пример здесь https://codesandbox.io/s/4x8v1mojq7 разрешает правдокументальную allow-top-navigation но codesandbox предотвращает перенаправление фрейма, поэтому, если мы попробуем https://4x8v1mojq7.codesandbox.io/, то есть url, созданный с помощью codeandbox, мы может видеть перезагрузку верхнего кадра.

Как я уже сказал в комментариях, по крайней мере Chrome 64.0.3282.167, когда мы делегируем все, кроме разрешенной навигации, когда iframe пытается перенаправить верхний фрейм, он генерирует исключение. В Firefox по-разному по-разному (не менее 58.0.2). Firefox запрещает верхнюю навигацию, но продолжает код.

Итак, как вывод, лучший подход, на мой взгляд, или сочетание sanbox и onunload или просто onunload. Конечно, если это будет возможно, Content-Security-Policy является самым безопасным и более гибким способом. Это зависит от реализации. Это почти невозможно. Я думаю, что не нужно использовать код на стороне сервера, чтобы выполнить идеальное решение. Есть белый список для проверки, как этот API https://developers.google.com/safe-browsing/v4/, и есть черный список для проверки, посмотрите это сообщение https://security.stackexchange.com/questions/32058/look-for-url-blacklists-of-malicious-websites.

Ответ 2

Если у вас есть контроль над всеми вашими фреймами, вы можете реализовать взаимодействие между фреймами с postMessage. Поток:

  1. Кадр хочет выполнить перенаправление - он отправляет сообщение родительскому кадру с запросом на перенаправление.
  2. Родительский кадр выполняет перенаправление и знает, какой кадр вызвал перенаправление.

родитель:

window.addEventListener("message", (event) => {
    // show message source (your frame)
    console.log(event.source);

    const message = event.data;
    console.log('Frame ID: ${message.frameId}');

    if(message.messageType === "redirect") {
        window.location.href = message.redirectUrl;
    }
});

Детский каркас:

function redirect(url) {
    var message = {
        messageType: "redirect",
        frameId: "frame1"
        redirectUrl: url
    }
    window.parent.postMessage(message, "*");
}

Ответ 3

Вы можете показать диалоговое окно перед перенаправлением на другой домен/приложение, а затем пользователь может решить - остаться или оставить текущее приложение. Вы также можете отслеживать текущую цель (т.е. iframe в вашем случае).

window.onbeforeunload = function (e) {
  console.log(e.currentTarget.location.href);
  return 'Stop redirection. Show dialog box.';
};

Ответ 4

Из отдельных iframes вы можете установить cookie, когда происходит перенаправление? Скажем, это произошло из iframe1, вы можете установить cookie как

document.trackFrame = "FrameName=iframe1";  

И как только перенаправление завершится, вы можете попробовать прочитать файл cookie и определить, какой iframe вызвал перенаправление?