Mail.ruПочтаМой МирОдноклассникиВКонтактеИгрыЗнакомстваНовостиКалендарьОблакоЗаметкиВсе проекты

Перехватить редирект JS

Профи (765), на голосовании 1 год назад
я пишу юзерскрипт, который при попытке сайта сделать редирект выдавал бы пользователю запрос на подтверждение этого самого редиректа.

с window.open все сработало, а вот с location.assign, location.replace и location.href - никак. есть ли способы перехватить это?

 (function() { 
let w = window.unsafeWindow??window;
if(w.top != w.self) return;

w.ropen = w.open;
w.open = function(u){
if(confirm(`Перейти на "${u}"?`)) w.ropen(u);
}

w.location.rreplace = w.location.replace;
w.location.replace = function(u){
if(confirm(`Перейти на "${u}"?`)) w.location.rreplace(u);
}

w.location.rassign = w.location.assign;
w.location.assign = function(u){
if(confirm(`Перейти на "${u}"?`)) w.location.rassign(u);
}

let gp = Object.getOwnPropertyDescriptor(location, 'href');
gp.set = function(u){
if(confirm(`Перейти на "${u}"?`)) location.rassign(u);
}
Object.defineProperty(location, 'href', gp);
})();
Голосование за лучший ответ
Professional Professional Мудрец (15955) 1 год назад
К сожалению, перехват редиректа, особенно при использовании `location.assign`, `location.replace` или изменении `location.href`, представляет существенные ограничения из-за безопасности браузеров. Это связано с политиками безопасности, предотвращающими злоумышленников от перехвата и изменения перенаправлений пользователей на вредоносные веб-сайты или действия.

Ваш скрипт может работать в контексте расширения браузера, такого как расширение для Chrome или Firefox, которые имеют больше привилегий, чем обычные юзерскрипты, но даже в этом случае вряд ли удастся перехватить перенаправление, созданное внутри страницы.

Однако, если ваш скрипт работает в контексте расширения и использует права для мониторинга событий браузера, вы можете попытаться перехватить событие `beforeunload`. Это событие запускается перед тем, как страница будет перенаправлена на другой URL. Однако этот подход также не гарантирует полный контроль над всеми типами перенаправлений, и его использование может быть ограничено политиками безопасности браузера.

Пример перехвата события `beforeunload` в расширении для Chrome:

```javascript
// Пример для Chrome расширения

// Функция, которая будет вызываться перед перенаправлением
function handleBeforeUnload(event) {
// Отменяем перенаправление и показываем запрос на подтверждение
event.preventDefault();
event.returnValue = ''; // Необходимо для Chrome
const url = event.currentTarget.location.href;
if (confirm(`Перейти на "${url}"?`)) {
// Продолжаем перенаправление после подтверждения
event.currentTarget.location.assign(url);
}
}

// Добавляем обработчик события beforeunload
window.addEventListener('beforeunload', handleBeforeUnload);
```

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

Пожалуйста, имейте в виду, что использование таких методов может нарушить политики безопасности браузера, а также оно может привести к плохому пользовательскому опыту. Пользователи обычно ожидают, что перенаправления будут выполняться без вмешательства, если это не обусловлено понятными обстоятельствами.
Профи (765) 1 год назад
это нужно, в первую очередь, для обхода систем обнаружения adblock, а так же для защиты от назойливой рекламы через window.open . в скрипте планируется список доменов, на которых он будет действовать
Руслан Идрисов Мастер (2084) 1 год назад
Чтобы перехватить редиректы, осуществляемые через `location.assign`, `location.replace` или `location.href`, вам необходимо скрыть стандартное свойство `location`, а затем создать новое свойство, которое будет обрабатывать перенаправления и выдавать запрос на подтверждение перед переходом.

Следующий код показывает, как это можно сделать:

```javascript
(function() {
let w = window.unsafeWindow || window;
if (w.top !== w.self) return;

// Скрыть стандартное свойство location
let hiddenLocation = w.location;
Object.defineProperty(w, 'location', {
get() {
return hiddenLocation;
},
set(u) {
if (confirm(`Перейти на "${u}"?`)) {
hiddenLocation.assign(u);
}
}
});
})();
```

Приведенный выше код перехватывает обращения к `location`, создает новое свойство и проверяет перенаправления через `location.assign`, `location.replace` или `location.href`. Затем он выдает запрос на подтверждение и выполняет перенаправление, если пользователь соглашается.

Обратите внимание, что этот код должен быть включен в ваш юзерскрипт или добавлен в расширение браузера, такое как Tampermonkey или Greasemonkey.
Профи (765) 1 год назад
не работает, скрипт выполняется через Tampermonkey, выдает ошибку: Cannot redefine property
Руслан Идрисов Мастер (2084) nekit, Ошибка "Cannot redefine property" возникает, когда вы пытаетесь повторно определить свойство, которое уже было определено или заблокировано для переопределения. В данном случае, скрипт пытается повторно определить свойство `location`, что вызывает ошибку. Ошибка возникает потому что свойство `location` является неизменным (immutable) и нельзя переопределить его. Вместо попытки переопределения `location`, вы можете попробовать создать новое свойство с другим именем для перехвата перенаправлений: ```javascript (function() { let w = window.unsafeWindow || window; if ( w.top !== w.self) return; // Создать новое свойство для перехвата перенаправлений Object.defineProperty(w, 'redirectLocation', { get() { return w.location; },
Руслан ИдрисовМастер (2084) 1 год назад
return w.location;
},
set(u) {
if (confirm(`Перейти на "${u}"?`)) {
w.location.assign(u);
}
}
});
})();
```

Теперь вы можете использовать свойство `redirectLocation` вместо `location` для перехвата перенаправлений. Например, вместо `location.assign(u)` вы можете использовать `redirectLocation.assign(u)`.
Руслан ИдрисовМастер (2084) 1 год назад
Места не хватило
Профи (765) Руслан Идрисов, так весь смысл скрипта в том, чтобы при попытке сайта выполнить редирект выдавалось предупреждение,а сайты используют location, а не какой-нибудь redirectLocation
Sergio 2.1 Оракул (67356) 1 год назад
К сожалению, нет простого способа перехватить редиректы, вызванные изменением location.href, location.assign или location.replace. Но вы можете использовать событие beforeunload для отображения диалогового окна с запросом на подтверждение перед покиданием страницы. Но это не позволит вам изменить URL-адрес назначения.
 window.onbeforeunload = function(e) { 
e.returnValue = 'Вы уверены, что хотите покинуть сайт?';
};
Похожие вопросы