Ответы пользователя по тегу Расширения для браузеров
  • Как изменить FormData?

    @zkrvndm
    Софт для автоматизации
    Это делается через контент-скрипт. При помощи контент-скрипт инжектиие на ВК свой код и уже далее через вставленный скрипт перехватываете POST-запросы, если надо - меняете.

    P. S. Просто я не уверен, что chrome.webRequest.onBeforeRequest позволяет редактировать тело запроса, посмотрите документацию - скорее всего не позволяет.
    Ответ написан
  • Веб браузер без рекламы?

    @zkrvndm
    Софт для автоматизации
    Ни один из известных мне браузеров не умеет блокировать рекламу Яндекса или YouTube самостоятельно.

    Однако решение есть:

    1. Установите браузер Vivaldi, только не надо в самом Vivaldi включать блокировку рекламы(!).

    2. Далее в браузере Vivaldi ставите 2 этих расширения:
    https://chrome.google.com/webstore/detail/adguard-...
    https://chrome.google.com/webstore/detail/adguard-...

    3. Повторюсь, не надо включать встроенный в браузер блокировщик, используйте расширения выше, они лучше.

    Эти 2 расширения работают в связке и могут блокировать абсолютно любую рекламу. Сможете смотреть ролики на YouTube без рекламы, видеть результаты поиска БЕЗ назойливых плашек Яндекс.Директ и многое другое. Покопайтесь потом сами в настройках расширения Adguard Антибаннер, там все есть.

    P. S. Например, так я читаю новости на Яндекс:
    60e80f8f3e1f9785438945.png
    Как видно, ни одного рекламного виджета справа) Просто пустое место.
    Ответ написан
    2 комментария
  • С помощью какого расширения можно извлечь все ссылки из групп в виде списка в браузере Google Chrome?

    @zkrvndm
    Софт для автоматизации
    Откройте консоль браузера и используйте:
    links = document.querySelectorAll('a[href]');
    for (var n = 0; n < links.length; n++) {
        console.log(links[n].href);
    }

    Выведет все ссылки с текущей страницы.
    Ответ написан
    2 комментария
  • Как передавать сообщения из popup.js в content.js?

    @zkrvndm
    Софт для автоматизации
    Для отправки сообщения из popup-окна в content-скрипт нужно выполнить в popup-окне:
    chrome.tabs.query({}, function(tabs) {
    	for (i = 0; i < tabs.length; i++) {
    		chrome.tabs.sendMessage(tabs[i].id, 'Сообщение, которое нужно передать');
    	}
    });

    Код выше перебирает все вкладки и отправляет во все существующие вкладки указанное сообщение.

    На стороне content-скрипта для приема сообщения должен стоять обработчик:
    chrome.extension.onMessage.addListener(function(msg) {
    	console.log('Принято сообщение: ' + msg);
    });
    Ответ написан
    5 комментариев
  • Как делать запросы через множество http-прокси одновременно?

    @zkrvndm Автор вопроса
    Софт для автоматизации
    Поковырял мануалы и узнал, что оказывается Firefox позволяет работать с множеством прокси разом. Набросал код для совершения запросов через произвольные прокси хоть одновременно, хоть в разнобой.

    Содержимое для вашего background.js:
    Нажмите, чтобы раскрыть код
    // Функция для совершения запросов:
    
    function getText(link, timeout, options) {
    	
    	// Возвращаем промис для удобства:
    	
    	return new Promise(function(endPromise) {
    		
    		// Конвертируем опции запроса в строку:
    		var bs64 = btoa(JSON.stringify(options));
    		
    		// Прячем опции в хеше:
    		var uobj = new URL(link);
    		uobj.hash = '#rp:'+bs64;
    		var new_url = uobj.href;
    		
    		// Создаем новое соединение:
    		var xhr = new XMLHttpRequest();
    		
    		// Открываем соединение:
    		xhr.open('GET', new_url);
    		
    		// Указываем таймаут:
    		xhr.timeout = timeout;
    		
    		// Функция для обработки результата:
    		
    		xhr.onreadystatechange = function() {
    			
    			// Если запрос был полностью завершен:
    			
    			if (xhr.readyState === XMLHttpRequest.DONE) {
    				
    				// Если запрос успешный:
    				
    				if (xhr.status === 200) {
    					
    					// Возвращаем текст ответа:
    					endPromise(xhr.responseText);
    					
    				}
    				
    				// Если запрос не успешный:
    				
    				else {
    					
    					endPromise(false); // Возвращаем false
    					
    				}
    				
    			}
    			
    		}
    		
    		xhr.send(); // Отправляем запрос
    		
    	});
    	
    }
    
    // Обработчик для проксирования некоторых запросов:
    
    browser.proxy.onRequest.addListener(function(request) {
    	
    	// Считываем хеш из адреса запроса:
    	var hash = new URL(request.url)['hash'];
    	
    	// Если хеш содержит
    	// параметры запроса:
    	
    	if (/^#rp:/.test(hash)) {
    		
    		// Получаем из хеша параметры запроса и расшифровываем:
    		var options = JSON.parse(atob(hash.replace(/^#rp:/, '')));
    		
    		// Если в параметрах запроса есть прокси:
    		
    		if (typeof options['proxy'] == 'object') {
    			
    			// Используем эту прокси:
    			return options['proxy'];
    			
    		}
    		
    		// Если в опциях нет прокси:
    		
    		else {
    			
    			// Не используем прокси:
    			return { 'type': 'direct' };
    			
    		}
    		
    	}
    	
    	// Если в хеше нет параметров:
    	
    	else {
    		
    		// Не используем прокси:
    		return { 'type': 'direct' };
    		
    	}
    	
    }, { urls: [ '<all_urls>' ] });
    
    // Обработчик для автоматической авторизация на http-прокси:
    
    browser.webRequest.onAuthRequired.addListener(function(request) {
    	
    	// Считываем хеш из адреса запроса:
    	var hash = new URL(request.url)['hash'];
    	
    	// Если хеш содержит
    	// параметры запроса:
    	
    	if (/^#rp:/.test(hash)) {
    		
    		// Получаем из хеша параметры запроса и расшифровываем:
    		var options = JSON.parse(atob(hash.replace(/^#rp:/, '')));
    		
    		// Если в параметрах запроса есть прокси:
    		
    		if (typeof options['proxy'] == 'object') {
    			
    			// Если в параметрах тип прокси http:
    			
    			if (options['proxy']['type'] == 'http') {
    				
    				// Отдаем логин с паролем для авторизации:
    				
    				return {
    					'authCredentials': {
    						'username': options['proxy']['username'],
    						'password': options['proxy']['password']
    					} 
    				};
    				
    			}
    			
    		}
    		
    	}
    	
    }, { urls: [ '<all_urls>' ] }, [ 'blocking' ]);
    
    // Обработчик для редактирования исходящих заголовков в запросах:
    
    browser.webRequest.onBeforeSendHeaders.addListener(function(request) {
    	
    	// Считываем хеш из адреса запроса:
    	var hash = new URL(request.url)['hash'];
    	
    	// Если хеш содержит
    	// параметры запроса:
    	
    	if (/^#rp:/.test(hash)) {
    		
    		// Получаем из хеша параметры запроса и расшифровываем:
    		var options = JSON.parse(atob(hash.replace(/^#rp:/, '')));
    		
    		// Берём массив заголовков запроса:
    		var headers = request.requestHeaders;
    		
    		// Перебираем заголовки в обратном порядке:
    		
    		for (var n = headers.length - 1; n >= 0; n--) {
    			
    			// Вытаскиваем название текущего заголовка:
    			var header = headers[n].name.toLowerCase();
    			
    			// Если текущий заголовок это Origin, Referer или Cookie:
    			
    			if (header == 'origin' || header == 'referer' || header == 'cookie') {
    				
    				// Удаляем заголовок:
    				headers.splice(n, 1);
    				
    			}
    			
    		}
    		
    		// Если передан Origin:
    		
    		if (options['origin']) {
    			
    			// Добавляем заголовок Origin в массив заголовков запроса:
    			headers.push({ name: 'Origin', value: options['origin'] });
    			
    		}
    		
    		// Если передан Referer:
    		
    		if (options['referer']) {
    			
    			// Добавляем заголовок Referer в массив заголовков запроса:
    			headers.push({ name: 'Referer', value: options['referer'] });
    			
    		}
    		
    		// Если передан Cookie:
    		
    		if (options['cookie']) {
    			
    			// Добавляем заголовок Cookie в массив заголовков запроса:
    			headers.push({ name: 'Cookie', value: options['cookie'] });
    			
    		}
    		
    		// Возвращаем изменённый
    		// массив заголовок запроса:
    		return {requestHeaders: headers};
    		
    	}
    	
    }, {urls: [ '<all_urls>' ] }, [ 'blocking', 'requestHeaders' ]);
    
    // Обработчик для редактирования входящих заголовков:
    
    browser.webRequest.onHeadersReceived.addListener(function(request) {
    	
    	// Считываем хеш из адреса запроса:
    	var hash = new URL(request.url)['hash'];
    	
    	// Если хеш содержит
    	// параметры запроса:
    	
    	if (/^#rp:/.test(hash)) {
    		
    		// Берём массив заголовков запроса:
    		var headers = request.responseHeaders;
    		
    		// Перебираем заголовки в обратном порядке:
    		
    		for (var n = headers.length - 1; n >= 0; n--) {
    			
    			// Вытаскиваем название текущего заголовка:
    			var header = headers[n].name.toLowerCase();
    			
    			// Если это установка куков:
    			
    			if (header == 'set-cookie') {
    				
    				// Удаляем заголовок:
    				headers.splice(n, 1);
    				
    			}
    			
    		}
    		
    		// Добавляем заголовок, что ответ должен быть доступен всем:
    		headers.push({ name: 'Access-Control-Allow-Origin', value: '*' });
    		
    		// Возвращаем изменённый
    		// массив заголовок запроса:
    		return {responseHeaders: headers};
    		
    	}
    	
    }, { urls: [ '<all_urls>' ] }, [ 'blocking', 'responseHeaders' ]);

    Пример совершения запроса через socks5-прокси:
    await getText('https://yandex.ru', 60000, {
    	'proxy': {
    		'type': 'socks',
    		'host': '185.38.84.111',
    		'port': '65234',
    		'username': 'тут_логин',
    		'password': 'тут_пароль'
    	},
    	'origin': 'https://yandex.ru',
    	'referer': 'https://yandex.ru/test',
    	'cookie': 'test1=123; iii=ooo'
    });

    Пример совершения запроса через http-прокси:
    await getText('https://yandex.ru', 60000, {
    	'proxy': {
    		'type': 'http',
    		'host': '185.38.84.111',
    		'port': '65233',
    		'username': 'тут_логин',
    		'password': 'тут_пароль'
    	},
    	'origin': 'https://yandex.ru',
    	'referer': 'https://yandex.ru/test',
    	'cookie': 'test1=123; iii=ooo'
    });

    Вы можете также передавать произвольные Origin, Referer и Cookie, чтобы получше замаскироваться.
    Ответ написан
    Комментировать
  • Как удалить js-скрипт с html-страницы в Сhrome до его выполнения?

    @zkrvndm
    Софт для автоматизации
    Потому что Google Chrome начиная с этого года потихоньку перекрывает возможность редактирования запросов, типа это небезопасно, как результат - функционал у блокировщиков реклам потихоньку отваливается. Радует что хоть Firefox не стал идти на поводу у Google в этом плане. Конкретно вам же рекомендую использовать системный блокировщик AdGuard для Windows, там можно прописать любые правила наплевав на мнение браузера.
    Ответ написан
  • Как правильно слушать порт в расширении хрома?

    @zkrvndm
    Софт для автоматизации
    Каждую секунду отправляйте из контент-скрипта сообщение в фоновый процесс:
    chrome.extension.sendMessage('Ваше сообщение');

    В фоновом процессе слушайте приходящие сообщения:
    chrome.extension.onMessage.addListener(function(message) {
    	console.log('Принято сообщение: ' + message);
    });

    Если связь с определенной вкладкой потеряна, пересоздаете его или обновляйте.

    P. S. Существуют и иные способы предотвратить заморозку вкладки, если интересно, расскажу.
    Ответ написан
  • Замена конкретного текста на странице с помощью JS?

    @zkrvndm
    Софт для автоматизации
    Для автозамены текста категорически нельзя использовать innerHTML, так как при его использовании будут слетать обработчики на элементах, вы так просто сломайте сайт.

    Для автозамены текста просто перебирайте все текстовые узлы на странице и конкретно их (текстовые узлы) уже меняйте и корректируйте как вам надо.

    Это вам поможет:
    Как перебрать все текстовые узлы на странице?
    Ответ написан
    1 комментарий
  • Как в расширении для chrome скачивать с без учёта CORS и CORB?

    @zkrvndm
    Софт для автоматизации
    Пример кода для background.js - для коррекции заголовков ответа и обхода CORS:
    // Обработчик для правки заголовков ответа:
    
    chrome.webRequest.onHeadersReceived.addListener(
    
        function(info) {
    	
    		var headers = info.responseHeaders; // Получаем массив отсылаемых заголовков
    		
    		// Обходим массив полученных заголовков:
    		
    		for (var i=headers.length-1; i>=0; --i) {
    			
    			var header = headers[i].name.toLowerCase(); // Считываем название того или иного заголовка
    			
    			// При наличии совпадений, удаляем заголовок нахрен:
    			
    			if (header == 'content-security-policy' || header == 'access-control-allow-origin') { 
    				headers.splice(i, 1);
    			}
    			
    		}
    		
    		// Добавляем свой собственный разрешающий заголовок:
    		headers.push({name: 'Access-Control-Allow-Origin', value: '*'});
    		
    		return {responseHeaders: headers}; // Вовращаем почищенный массив заголовков назад
    		
        },
    	
        { urls: [ '<all_urls>' ], types: [ 'xmlhttprequest' ] },
    	
        ['blocking', 'responseHeaders']
    	
    );


    При этом в манифесте расширения у вас должны быть прописаны разрешения:
    ...
    "permissions" : [ "webRequest", "webRequestBlocking", "<all_urls>" ],
    "background" : { "persistent": true, "scripts": [ "background.js" ] },
    ...
    Ответ написан
    Комментировать
  • Как удалить абсолютно все Cookie в браузере используя Chrome API?

    @zkrvndm Автор вопроса
    Софт для автоматизации
    Пример кода для background.js вашего расширения:
    chrome.cookies.getAll({}, function(cookies) {
    	
    	var count = cookies.length;
    	
    	console.log('Найдено Cookie '+count+' шт.');
    	console.dir(cookies);
    
    	for (var n = 0; n < cookies.length; n++) {
    		
    		var details = {
    			'name': cookies[n]['name'],
    			'storeId': cookies[n]['storeId'],
    			'url': 'https://' + cookies[n]['domain'] + cookies[n]['path']
    		};
    		
    		chrome.cookies.remove(details, function(result) {
    			count--;
    			if (count === 0) {
    				console.log('Cookie успешно очищены:');
    				chrome.cookies.getAll({}, function(cookies) { console.dir(cookies); });
    			}
    		});
    		
    	}
    
    });
    Ответ написан
    Комментировать
  • Какие способы защиты клиентов при разработке расширения?

    @zkrvndm
    Софт для автоматизации
    Ну грузи свои скрипты с github из фонового процесса расширения и будет тебе счастье.
    Ответ написан
    Комментировать
  • Как в google extensions прокинуть переменную на активную вкладку?

    @zkrvndm
    Софт для автоматизации
    В фоновой вкладке выполняйте:
    chrome.tabs.query({}, function(tabs) {
    	for (i = 0; i < tabs.length; i++) {
    		chrome.tabs.sendMessage(tabs[i].id, 'Привет мир!');
    	}
    });

    Во все вкладки будет передано сообщение Привет мир!

    Для получения сообщений на целевой вкладке внутри контент-скрипта ставите обработчик:
    chrome.extension.onMessage.addListener(function(message) {
    	console.log('Получено сообщение: ' + message);
    });

    Разумеется это просто пример, на деле это все нужно допиливать напильником под себя.

    P. S. Если нужно передать сообщение только и исключительно в активную вкладку, то ставите такой фильтр:
    chrome.tabs.query({active: true}, function(tabs) {
    	for (i = 0; i < tabs.length; i++) {
    		chrome.tabs.sendMessage(tabs[i].id, 'Привет мир!');
    	}
    });
    Ответ написан
  • Расширение для chrome под web telegram не работает click(), что делаю не так?

    @zkrvndm
    Софт для автоматизации
    Для того, чтобы сработала отправка сообщения, нужно вызывать на кнопке SEND событие MOUSEDOWN:
    document.querySelector('span[data-content="Send"]').dispatchEvent(new MouseEvent('mousedown', { bubbles: true }));
    Ответ написан
    1 комментарий
  • Как получить значения chrome storage в content script?

    @zkrvndm
    Софт для автоматизации
    Если вы вот так сохраняйте контент:
    var mail = document.getElementById("mail").value;
    То я вам скажу, что он так не сохраняется.

    Нужно так:
    chrome.storage.local.set({mail: document.getElementById("mail").value}, function() {
        console.log('Сохранено' );
    });
    Ответ написан
  • Как вырезать проверку на adblock из расширения для хрома?

    @zkrvndm
    Софт для автоматизации
    Удалите AdBlock, вместо него поставьте ПРОГРАММУ Adguard, он тоже блочит рекламу на сайтах, но при этом не является расширением.
    Ответ написан
    Комментировать
  • Можно ли предотвратить засыпание свернутой вкладки, или закрытого браузера Google Chrome?

    @zkrvndm
    Софт для автоматизации
    Да, по идее можно запретить выгрузку вкладок применив 2 приема.

    Добавьте в background.js:
    chrome.tabs.onCreated.addListener(function(tab) {
        chrome.tabs.update(tab.id, {
            autoDiscardable: false
        });
    });
    
    chrome.tabs.onReplaced.addListener(function(tabId) {
        chrome.tabs.update(tabId, {
            autoDiscardable: false
        });
    });
    
    chrome.runtime.onInstalled.addListener(function(details) {
        chrome.tabs.query({}, function(tabs) {
            tabs.forEach(function(tab) {
                chrome.tabs.update(tab.id, {
                    autoDiscardable: false
                });
            });
        });
    });

    В манифесте расширения у вас должны быть соответствующие разрешения:
    ...
    "permissions" : [ "tabs" ],
    "background" : { "persistent": true, "scripts": [ "background.js" ] },
    ...

    Кроме того, на активной вкладке необходимо разместить mp3-трек и запустить его в бесконечном цикле:
    <video id="antifreeze" style="position: fixed; right: 30px; bottom: 30px; z-index: 99999; height: 55px; width: 300px;" controls loop name="media">
        <source src="https://qna.habr.com/silence.mp3" type="audio/mpeg">
    </video>

    Начиная с 81 версии хрома, вкладки замораживаются через 5 минут, после сворачивания. Исключением являются вкладки в которых воспроизводится какой-нибудь медиконтент (видео там или музыка).
    Ответ написан
    7 комментариев
  • Можно ли использовать расширения Chrome для написания бота для сайта? Или можно использовать консоль?

    @zkrvndm
    Софт для автоматизации
    Да, возможно. Расширения для хром позволяют запускать произвольный JavaScript-код на сайтах, нужная вам опция называется контент-скриптами:
    chrome-ext.blogspot.com/2014/02/content-scripts.html
    Ответ написан
    Комментировать
  • Почему не работает функция shExpMatch внутри pacScript?

    @zkrvndm Автор вопроса
    Софт для автоматизации
    Я нашел в чем проблема. Оказалось, что в переменную url внутри pac-скрипта полный адрес открытой страницы передается только если сайт открыт по протоколу http. В том случае, если сайт открывается по протоколу https браузер режет пути оставляя только домен:
    spoiler
    The URL being accessed. The path and query components of https:// URLs are stripped. In Chrome (versions 52 to 73), you can disable this by setting PacHttpsUrlStrippingEnabled to false in policy or by launching with the --unsafe-pac-url command-line flag (in Chrome 74, only the flag works, and from 75 onward, there is no way to disable path-stripping; as of Chrome 81, path-stripping does not apply to HTTP URLs, but there is interest in changing this behavior to match HTTPS); in Firefox, the preference is network.proxy.autoconfig_url.include_path.

    К большому моему сожалению это и изменить то нельзя, так как флага PacHttpsUrlStrippingEnabled в настройках хрома я не нашел, а запуск через опцию --unsafe-pac-url не помогает. Даже и не знаю, что теперь делать(
    Ответ написан
    Комментировать
  • Есть ли Расширение для удаление миксов в рекомендации на ютуб?

    @zkrvndm
    Софт для автоматизации
    Используйте любой удобный вам блокировщик рекламы, ими можно не только рекламу удалять, но и произвольные элементы со страницы. Рекомендовал бы присмотреться к расширению от Adguard.
    Ответ написан
    Комментировать
  • Как изменить свойство isTrusted у события на true?

    @zkrvndm Автор вопроса
    Софт для автоматизации
    К сожалению, я тоже не нашел прямого способа поменять у события свойство isTrusted на true, но есть обходные пути, которые позволяют добиться похожего результата. Дело в том, что используя возможности API расширений мы можем отредактировать скрипты-обработчики целевого сайта так, чтобы там больше не было проверки свойства isTrusted или чтобы эта проверка всегда возвращала положительный результат. Это как бы и есть решение.
    Ответ написан