• Почему не работает директива unsafe-inline в расширении для Google Chrome?

    @zkrvndm Автор вопроса
    Софт для автоматизации
    Спустя час поисков нашел ответ на свой вопрос:
    ...установка политики, которая включает «unsafe-inline», не будет иметь никакого эффекта.

    Начиная с Chrome 46, встроенные скрипты можно добавить в белый список, указав в политике хэш исходного кода в кодировке base64. Этот хэш должен иметь префикс используемого алгоритма хеширования (sha256, sha384 или sha512).

    Другими словами на страницах расширения в принципе нельзя никак применить политику unsafe-inline.
    Всегда будет выдавать ошибку:
    'content_security_policy': Ignored insecure CSP value "'unsafe-inline'" in directive 'script-src'.
    Ответ написан
    Комментировать
  • Как сделать редактируемое в браузере изображение?

    @zkrvndm
    Софт для автоматизации
    Изучите что такое CANVAS и с чем его едят:
    old.code.mu/books/javascript/canvas/osnovy-raboty-...
    Ответ написан
    Комментировать
  • Как можно оптимизировать нагрузку на компьютер?

    @zkrvndm
    Софт для автоматизации
    Описанную вами задачу можно потенциально можно через 1 браузер решить. Создаете специальное расширение, которое авторизуется на целевом сайте и запоминает куки куда-нибудь в базу данных, затем расширение очищает куки и повторяет процесс авторизации заново. И так 30 раз, пока вы не скопите 30 кук от всех ваших 30 учеток.

    Дальше же прожимать кнопки дело техники, смотрите какие-запросы отправляются при нажатии кнопки и симулируйте POST-запросы из фонового процесса расширения с передачей нужных кук в заголовках.

    Честно сказать, здесь даже браузер не нужен, если при авторизации не используется никаких хитрых капч, проблему и вовсе можно было бы решить одним php скриптом.
    Ответ написан
    Комментировать
  • Как изменить свойство isTrusted у события на true?

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

    @zkrvndm
    Софт для автоматизации
    Оплату без комиссии принимать на сайте онлайн нельзя. Все платежные агрегаты предоставляющие услуги банковского эквайринга берут за это комиссию, в конце концов, это их хлеб.

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

    Кстати, говоря о приеме платежей, есть интересный вариант использовать для приема оплаты на сайте сервисы для переводов с карты на карту. У этого способа преимущество в том, что вам фактически не надо нигде регистрироваться, так переводы вы получаете напрямую на свою карту, как физическое лицо.
    Ответ написан
    Комментировать
  • Как взять последний td у каждого tr?

    @zkrvndm
    Софт для автоматизации
    Можно удалить конечно, а можно просто скрыть, сделать невидимым через CSS:
    table tr td:nth-last-child(1) {
        display: none;
    }

    Первый с конца td внутри всех tr будет скрыт.
    Ответ написан
    Комментировать
  • Как реализовать групповой видеозвонок на сайте?

    @zkrvndm
    Софт для автоматизации
    Пользуйтесь поиском, вот что нашел на первой странице Яндекса:
    https://trueconf.ru/blog/baza-znaniy/kak-dobavit-v...
    Ответ написан
  • Как грамотно пропарсить скопированные колонки с google sheets?

    @zkrvndm
    Софт для автоматизации
    У меня однажды возникла задача, спарсить данные с Google таблицы не используя их API.

    В итоге, вот какое решение я придумал:
    googleTableParse('https://docs.google.com/spreadsheets/d/<код документа>/edit');
    
    // Функция для парсинга Google таблицы:
    
    async function googleTableParse(link) {
    	
    	var url = link.replace(/edit$/g, 'export?format=zip');
    	var response = await fetch(url);
    	var zip = await response.blob();
    	var archive = await new JSZip().loadAsync(zip);
    	var files = Object.keys(archive.files);
    	var lists = Object.create(null);
    	for (var n = 0; n < files.length; n++) {
    		if (!files[n].includes('/') && files[n].includes('.html')) {
    			var blob = await archive.files[files[n]].async('blob');
    			var html = await blob.text();
    			var name = files[n].replace(/\.html$/g, '');
    			lists[name] = tableParser(html);
    		}
    	}
    	
    	console.log('Таблица и все листы в нём успешно спарсены:');
    	console.dir(lists);
    	
    }
    
    // Функция для парсинга html-кода таблицы из скачанного архива:
    
    function tableParser(html) {
    	
    	var doc = new DOMParser().parseFromString(html, "text/html");
    	
    	var th = doc.querySelector('table > tbody > tr').querySelectorAll('th, td');
    
    	var title = [];
    
    	for (var i = 0; i < th.length; i++) {
    
    		title.push(th[i].innerText);
    
    	}
    	
    	var tr = doc.querySelectorAll('table > tbody > tr');
    	
    	var array = [];
    	
    	for (var i = 1; i < tr.length; i++) {
    
    		var td = tr[i].querySelectorAll('th, td');
    		
    		var obj = {};
    		var add = 0;
    		
    		for (var y = 1; y < td.length; y++) {
    			
    			td[y].innerHTML = td[y].innerHTML.replace(/\<br\>/g, '{перенос строки}');
    			obj[title[y]] = td[y].innerText.replace(/\{перенос строки\}/g, "\n").trim();
    			if (obj[title[y]] !== '') {
    				add = 1;
    			}
    			
    		}
    		
    		if (add) {
    			array.push(obj);
    		}
    
    	}
    	
    	return array;
    	
    }


    Для работы функции должно выполнятся 2 условия:
    1. Должна быть подключена библиотека JSZip, которая позволяет работать с zip-архивами на JavsScript
    2. Каким-то образом вы должны добавить разрешающий заголовок Access-Control-Allow-Origin на все запросы к серверам Google. Лично я это сделал, через использование расширения и файла background.js но это не единственный вариант. Можно для выполнения кода использовать NodeJS или как-то проксировать процесс закачки файла.
    Ответ написан
    Комментировать
  • Как можно оптимизировать перенос текста с нижним подчеркиванием?

    @zkrvndm
    Софт для автоматизации
    Оберните название файла в блок и примените к нему стиль:
    word-break: break-all;
    Желательно блок выделить немного изменив фоновый цвет.

    Если не нравится, то еще можно так:
    text-overflow: ellipsis;
    Ответ написан
    3 комментария
  • Какую библиотеку javascript можно использовать для создания элементов выбора периода, как в Booking или на подобие того?

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

    @zkrvndm
    Софт для автоматизации
    Преобразуешь свой массив в JSON, генерируешь текстовый Blob в который записываешь полученный JSON, далее пакуешь Blob в zip-архив и спокойно шлёшь архив аяксом на сервер. Способ универсальный и применять его можно даже в браузере, может спасти в некоторых уникальных случаях, когда надо пересылать большие объёмы данных, с минимальной нагрузкой на сеть. Для работы с архивами на JavaScript существует замечательная библиотека JSZip.

    Если же вам интересна просто отправка массива в лоб, без сжатия и чисто для галочки, чтобы был бинарный тип у данных, тогда гляньте здесь:
    https://learn.javascript.ru/xhr-forms#post-s-multi...
    Там есть примеры POST запросов в бинарном виде.
    Ответ написан
    Комментировать
  • Как из iframe обратиться к родителю?

    @zkrvndm
    Софт для автоматизации
    Чтобы послать сигнал из фрейма в родительской документ, в родителе ставите обработчик message:
    window.addEventListener('message', function(event) {
    	var message = event.data;
    	console.log('Получено сообщение из фрейма: ' + message);
    });

    Далее внутри фрейма попробуйте выполнить:
    window.parent.postMessage('Какое-нибудь произвольное сообщение', '*');

    И увидите, как сработал обработчик в родителе. Разумеется вместо сообщения, вы можете послать наружу, например, высоту фрейма или вовсе какой-нибудь произвольный JS-код, который потом можно выполнить внутри обработчика.

    Больше информации вы можете добыть самостоятельно, через поиск Яндекса:
    https://yandex.ru/search/?text=JavaScript%20postMe...
    Если мой ответ помог, отметьте его решением.
    Ответ написан
    Комментировать
  • Как сделать определённые div-элементы в contenteditable неудаляемыми через backspace?

    @zkrvndm
    Софт для автоматизации
    Неудалямые элементы попробуйте разместить во вне редактора и отпозиционировать абсолютно, как вам нужно. Также вы можете перехватывать событие предшествующее удалению, отменять его и уже затем решать, разрешать удаление или нет.
    Ответ написан
    Комментировать
  • Как с помощью html страницы открытой в компе отправить запрос на активный порт localhost?

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

    Если хотите совершить классический AJAX запрос на свой локалхост, с чтением ответа, то вам сначала надо настроить заголовок Access-Control-Allow-Origin в NodeJS.
    Ответ написан
    Комментировать
  • Как отменить заморозку фоновых вкладок Google Chrome?

    @zkrvndm
    Софт для автоматизации
    Запретить заморозку вкладок можно при помощи Chrome API.

    Создайте пустое расширение и в 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
                });
            });
        });
    });


    Также имеет смысл отключить опцию:
    chrome://flags/#enable-heavy-ad-intervention
    Она отвечает за блокировку фреймов создающих слишком большую нагрузку по мнению Google и похрен, что бывают в природе сайты, в которых весь основной функционал предоставлен через фреймы.
    Ответ написан
  • Php-скрипт для заливки файлов на сайт?

    @zkrvndm
    Софт для автоматизации
    Если у вас VDS, то думаю вам подойдет спрутио:
    https://sprut.io/ru/
    Ответ написан
    Комментировать
  • Как заблокировать спамера?

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

    Если бюджет позволяет, то можно в форму обратной связи внедрить смс идентификацию, т. е. пока не введешь свой номер телефона и не подтвердишь его кодом из смс, форма просто не будет отправляться. Весьма надёжно.
    Ответ написан
    Комментировать
  • Реализовано ли в HTML резделение верстки по файлам?

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

    Обычно так никто не делает в наше время, но чисто технически да - это реализуемо.
    Ответ написан
    Комментировать
  • Загрузка изображений с камеры на сервер?

    @zkrvndm
    Софт для автоматизации
    После прикрепления фотки посмотрите, что там в инпуте на стороне клиента, вдруг каких-то параметров не хватает или фотка имеет нулевой размер. Если на первый взгляд все в порядке, попробуйте форму отправлять не аяксом, а обычным способом. Если даже это не поможет, тогда вижу два решения в лоб: отправить файл строкой или упаковать его сначала в zip архив перед отправкой и отправлять уже сам архив. Для генерации архива на стороне браузера можно использовать плагин JSZip, он вам выдаст Blob который уже можно спокойно переслать на сервер аяксом.
    Ответ написан
    Комментировать
  • Как имитировать ввод сообщения в WhatsApp Web?

    @zkrvndm Автор вопроса
    Софт для автоматизации
    Написал функцию для эмуляции ввода сообщения в WhatsApp Web:
    // Вызываем функцию для набора текста и отправки:
    
    textEnter('Проверка события ввода сообщения в мессенджере WhatsApp. Смотрим, отсылается ли информация о том, что собеседник в данный момент печатает сообщение.');
    
    // Функция для имитации ввода сообщения и его отправки:
    
    function textEnter(text) {
    	
    	var array = text.split(''); // Разбиваем текст по символам в массив
    	
    	// Ищем поле вввода сообщения и записываем ссылку на него в переменную:
    	
    	var div = document.querySelector('div#main div[contenteditable="true"]');
    	
    	div.focus(); // Передаём фокус на поле ввода
    	
    	// Запускаем эмулятор посимвольного ввода:
    	
    	var emulator = setInterval(function() {
    		
    		// Пока есть символы в сообщени:
    		
    		if (array.length > 0) {
    			
    			// Вводим символ:
    			var symbol = array.shift();
    			div.innerHTML = div.innerHTML + symbol;
    			
    			// Передаём клавиатурные события отвечающие за ввод:
    			div.dispatchEvent(new KeyboardEvent('keydown', { bubbles: true }));
    			div.dispatchEvent(new KeyboardEvent('keypress', { bubbles: true }));
    			div.dispatchEvent(new KeyboardEvent('keyup', { bubbles: true }));
    			div.dispatchEvent(new InputEvent('input', { bubbles: true }));
    			
    		}
    		
    		// Если все символы введены:
    		
    		else {
    			
    			clearInterval(emulator); // Отключаем эмулятор ввода
    			
    			// Ищем и жмем кнопку отправки сообщения собеседнику:
    			document.querySelector('span[data-icon="send"]').click();
    			
    		}
    		
    	}, 100);
    
    }

    Наверняка многим пригодится. Спасибо Mikhail Osher за наводку на правильный алгоритм действий)
    Ответ написан
    Комментировать