Как запретить браузеру загружать веб-приложение на ванильном JavaScript?

Я написал следующий сценарий Greasemonkey, чтобы запретить себе доступ к нескольким веб-приложениям (веб-сайтам), обычно я чувствую себя немного зависимым от них. Это самое близкое, что мне нужно, чтобы запретить моим браузерам отображать эти сайты:

// ==UserScript==
// @name        blocko
// @include     *
// ==/UserScript==

window.addEventListener('load', function() {
    let sites = ['example-1.com', 'example-2.com', 'example-3.com'];
    let dotTLD_andAllAfterIt = /\..+/;
    let href = window.location.href;
    for (let i = 0; i < sites.length; i++) {
        if (href.includes(sites[i])) {
            let domain = sites[i].replace(dotTLD_andAllAfterIt, '');
            document.body.innerHTML =`
                <div style = "direction: ltr; position: fixed; top: 0; z-index: 999999; display: block; width: 100%; height: 100%; background: red">
                  <p style = "position: relative; top: 40%; display: block; font-size: 66px; font-weight: bold; color: #fff; margin: 0 auto; text-align: center">
                    Enough with this ${domain} bullshit!
                  </p>
                </div>
          `;
        }
    }
}, true);

Я не удовлетворен своим достижением здесь, так как этот сценарий вводит меня на сайт, и мне нужно подождать 1/2/3/4 или даже 5 или более секунд в редких случаях, пока сайт не исчезнет и сообщение, которое я распечатаю на экране с красным вместо этого появится фон. Таким образом, я неохотно сталкиваюсь с содержанием сайта, чего я хочу избегать.

Я хочу запретить браузеру даже переходить на веб-сайт через JavaScript. Существует надстройка Chrome под названием «BlockSite», которая помогает с этим, и я попытался изучить его (огромный) исходный код, но не смог понять, как он предотвращает использование быть перемещенным на веб-сайт пользователя, в отличие от моего сценария выше, который перемещает пользователя на веб-сайт, но исчезает с веб-сайта. с сообщением через несколько секунд (после срабатывания события load).

Поделитесь, пожалуйста, способом полностью предотвратить переход на веб-сайт, как в случае с «BlockSite».

Собираетесь ли вы создать плагин / расширение для браузера или сценарий должен быть реализован внутри веб-сайта?

sultan 10.03.2018 15:05

Привет! Я не планирую создавать расширение для браузера. Функциональность должна работать в рамках определенного домена.

user9303970 10.03.2018 15:32

Отредактируйте файл hosts, включив в него что-то вроде 127.0.0.1 example-1.com. Может помочь простой поиск в Google («отредактируйте файл hosts, чтобы предотвратить доступ к веб-сайту»).

Iván Nokonoko 22.03.2018 13:00
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
5
3
563
4

Ответы 4

В качестве решения вы можете переопределить метод onclick для всех ссылок на своем веб-сайте. Затем решите, разрешить пользователю переходить по ссылке или нет.

const blackList = [`example-1.com`, `example-2.com`]

function onClick(event) {
  const href = this.href.match(/^(?:https?:)?(?://)?(?:[^@\n]+@)?(?:www\.)?([^:/\n]+)/i)
  if (!href) return
  const domain = href[1]
  if (blackList.includes(domain)) {
    event.stopPropagation()
    event.preventDefault()
    document.body.innerHTML =`
      <p>
        Enough with this ${domain} bullshit!
      </p>
    `;
  }
}

const elements = document.getElementsByTagName(`a`);
for(let element of elements) {
  element.onclick = onClick
}

.: ОБНОВИТЬ :.

Хорошо, позвольте мне объяснить приведенный выше код.

Код добавляет слушателя click ко всем ссылкам (<a href = "...">...</a>) вашей текущей страницы. Когда пользователь щелкает указанную выше функцию, запускается.

const href = this.href.match - мы извлекаем из части домена только href, чтобы сравнить, существует ли URL в нашем черном списке или нет -> if (blackList.includes(domain)).

this - относится к свойству ссылки href, для получения дополнительной информации проверьте этот статья.

Вот демонстрация, а вот исходный код.

Мы должны использовать регулярное выражение?

user9303970 17.03.2018 12:03

Пожалуйста, подумайте о добавлении некоторых комментариев там, где вы сочтете нужным.

user9303970 17.03.2018 14:23

@ user9303970 хорошо, я обновил свой ответ с некоторыми пояснениями

sultan 17.03.2018 15:33

Султан, вы тестировали код, я пытался проверить, для меня это не работает ... Кроме того, вы согласны дать несколько слов о регулярном выражении во втором обновлении, возможно, представьте его разные "контексты" или группы соответствия символов по их контексту.

user9303970 23.03.2018 03:14

@ user9303970 проверьте это здесь codeandbox.io/s/6xmq2pnl2k6xmq2pnl2k.codesandbox.io

sultan 23.03.2018 06:27

Вам нужно подождать, пока вы используете событие window load. Вместо этого вам нужно использовать событие DOMContentLoaded. Разница объясняется здесь на этот ответ.

Будет работать намного быстрее, если поменять

window.addEventListener('load', function() {
   //Your Code
}, true);

К

document.addEventListener("DOMContentLoaded", function(event) {
   //Your Code
});

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

Обновлять: Следующий абзац удален на основании комментариев

Но если вы хотите создать собственное расширение, вам нужно быть конкретным для браузера. Так же нужно писать разные расширения для разных браузеров.

Ваш последний абзац больше не соответствует действительности, поскольку большинство основных браузеров (включая Chrome, Firefox и Edge, но, к сожалению, не Safari) поддерживают более или менее тот же кроссбраузерный WebExtension API. Удобно, что WebExtension сценарии контента также очень похожи на пользовательские скрипты Greasemonkey / Tampermonkey, поэтому превращение пользовательского скрипта в автономное расширение довольно тривиально (в основном, просто добавьте файл manifest.json).

Ilmari Karonen 21.03.2018 20:45

@IlmariKaronen Я этого не знал, абзац удален.

Munim Munna 21.03.2018 20:53

Лучший способ заблокировать отображение сайта в вашем браузере - это сделать перед, который он загружает, с помощью CSS. Что-то вроде этого должно хорошо сработать:

/* hide all child elements of <body> */
body > * {
  display: none !important;
}
/* just in case, hide text directly inside <body> too */
body {
  color: transparent !important;
  font-size: 0px !important;
}
/* inject an overlay to show a message and to cover up anything that might
   still somehow be visible after the styles above */
body::before {
  content: 'Enough with this BS!';
  display: block;
  width: 100%;
  height: 100%;
  position: fixed;
  z-index: 999999;
  text-align: center;
  font-size: 36pt;
  font-family: sans-serif;
  color: red;
  background: black;
}

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

В качестве альтернативы вы также можете добиться аналогичного результата, заключив стиль в пользовательский сценарий и самостоятельно внедрив его на страницу. Вы можете использовать директиву заголовка @run-at document-start, чтобы пользовательский сценарий запускался как можно раньше, даже до загрузки страницы, что снова минимизирует риск отображения любого фактического содержимого страницы даже на короткое время:

// ==UserScript==
// @name        Enough with this BS
// @version     0.1
// @description Block any sites this script runs on with a rude message.
// @author      Ilmari Karonen
// @match       *://*.example.com/*
// @grant       none
// @run-at      document-start
// ==/UserScript==

var style = `
    /* hide all child elements of <body> */
    body > * {
      display: none !important;
    }
    /* just in case, hide text directly inside <body> too */
    body {
      color: transparent !important;
      font-size: 0px !important;
    }
    /* inject an overlay to show a message and to cover up anything that might
       still somehow be visible after the styles above */
    body::before {
      content: 'Enough with this ${location.hostname} BS!';
      display: block;
      width: 100%;
      height: 100%;
      position: fixed;
      z-index: 999999;
      text-align: center;
      font-size: 36pt;
      font-family: sans-serif;
      color: red;
      background: black;
    }`;

// Inject style into page
var styleElem = document.createElement( 'style' );
styleElem.type = 'text/css';
styleElem.textContent = style;
( document.head || document.documentElement ).appendChild( styleElem );

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

Обратите внимание, что приведенный выше сценарий не содержит никаких регулярных выражений для сопоставления сайтов, которые вы хотите заблокировать; вместо этого он использует @match выражения в заголовке пользовательского сценария, чтобы указать диспетчеру пользовательских сценариев запускать его только на определенных сайтах. (Заголовок примера выше просто блокирует весь контент на example.com и любых его поддоменах.)

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

(Также, возможно, стоит отметить, что я встроил таблицу стилей в код JS, используя Шаблонный литерал ES2015, поскольку строки JS старого стиля не могут охватывать несколько строк. Код, выделенный здесь на SO, похоже, еще не правильно понимает этот синтаксис, поэтому это выглядит немного забавно.)

  • Попробуйте это, если хотите остановить: документация window.stop (не может остановить загрузку документа, в котором он содержится)
  • Попробуй, если вы хотите предотвратить перезагрузку страницы / ссылку перенаправления: перед выгрузкой документация (не предотвращать автоматическую загрузку, но разрешить пользователю выбирать, переходить по ссылке или нет)

    window.onbeforeunload = function(e) {
    
      var dialogText = 'Are you sure?';
    
       e.returnValue = dialogText;
    
       return dialogText;
    
    };
    

Кажется, это лучший способ. Можете ли вы поделиться кодом, чтобы заблокировать доступ ко всем сайтам в данной коллекции?

user9303970 26.03.2018 07:45

Я повторно комментирую, только потому, что действительно не уверен, видели ли вы мой комментарий.

user9303970 27.03.2018 03:10

Я поднял ваш ответ, потому что это кажется наиболее многообещающим подходом.

user9303970 27.03.2018 03:10

thnx, у меня просто не хватает времени на демо-ответ) Я отредактировал свой ответ, наверное мой ответ для вас не очень полезен

Alex Nikulin 27.03.2018 09:04

Другие вопросы по теме