Случайны выбор дневника Раскрыть/свернуть полный список возможностей


Найдено 2236 сообщений
Cообщения с меткой

google chrome - Самое интересное в блогах

Следующие 30  »
rss_rss_hh_new

[Из песочницы] Не поставил favicon на сайте — получи двойной трафик от Chrome

Среда, 07 Сентября 2016 г. 16:59 (ссылка)

Впервые за пять лет разработки интернет-сайтов я столкнулся с весьма неожиданной проблемой, стоившей мне многих часов поиска, нервов и волос на голове. Внезапно я обнаружил, что на новом сайте, который у меня сейчас в разработке на локалхосте, дублируются INSERT запросы к БД. Отправляю один комментарий через форму, а в базу вставляются два. Если вы не знаете, как связана эта проблема с Chrome, favicon.ico и ModRewrite, то добро пожаловать под кат.



Нет, это не в глазах двоится



Разумеется, первое что пришло в голову — где-то в скрипте «двоится» запрос к базе данных. Например, такая «школьная ошибка»:



$query = "INSERT INTO table VALUES(...)";
$result = mysqli->query($query);
if ($result = mysqli->query($query)) {
...
}


Проверяю сто тысяч раз — нет. С кодом все в порядке. Значит браузер по какой-то причине отправляет данные дважды. Генерирую простенький тестовый скрипт с инкрементом сессионной переменной и — да! Вместо увеличения на единицу браузер упорно показывает увеличение переменной на два. Пробую вместо Хрома Сафари — нет такой проблемы. Далее идут поиски некорректно работающих яваскриптов, расширений для браузера, но все безрезультатно. Поиск по интернету давал схожие советы. Многие программисты в аналогичной ситуации вводили проверку на уникальность и отсекали дублирующиеся посты. Но баг то это решение не устраняет и я решил не останавливаться и найти причину такого поведения.



Наконец, причина была найдена. И так как решение нашел с трудом, на англоязычной девелоперской ветке, хочу поделиться им здесь. Все просто — виновника два: Google Chrome (и производные от него браузеры) и mod_rewrite в Apache.



Суть проблемы



Все просто. Особенность браузеров, построенных на платформе Crome в том, что они ищут файл favicon.ico для каждого сайта. И если его нет, то они все равно будут упорно его искать. При каждом обновлении страницы, отдельным запросом к серверу. А большинство .htaccess файлов в Apache имеют в себе строчки:



RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . /index.php


Руководствуясь этим правилом, получая запрос от браузера к несуществующему favicon.ico Apache послушно перенаправит его к файлу index.php и скрипт отработает дважды. Конечно, в большинстве случаев полноценные веб-приложения имеют проверку на уникальность и не пропускают повторяющиеся запросы. А сайты в большинстве случаев имеют файл favicon.ico. Но все же раз существует такая проблема, значит можно описать методы решения.



Варианты решения



Решение первое, самое простое: заведите на сайте favicon.ico. Chrome найдет его и успокоится.

Решение второе — немного изменить файл .htaccess на сервере. У меня блок правил mod_rewrite для всех проектов теперь будет выглядеть так:




RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
# Next line is to solve the Chrome and favicon.ico file issue.
# Without it browser sends two requests to script.
RewriteCond %{REQUEST_FILENAME} !favicon.ico
# RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]



Не поставил favicon? Получи двойной трафик от Chrome



Если вдуматься, то утверждение справедливо, ведь вместо того, чтобы отдать «статику», сервер будет запускать веб-приложение, которое в лучшем случае вернёт в браузер вместо иконки динамически сгенерированную 404 страницу. А в худшем — отработает полностью запуск главной страницы сайта. Получается, что не установив иконку на сайте (например, на одном популярном блоговом движке), разработчик вдвое увеличивает нагрузку на сервер от пользователей Google Chrome.



Вот, собственно и все. Надеюсь эта информация кому-то пригодится и сэкономит время.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/309436/

Метки:   Комментарии (0)КомментироватьВ цитатник или сообщество
rss_rss_hh_new

Выбираем html-парсер для Apache.JMeter

Вторник, 23 Августа 2016 г. 07:18 (ссылка)

Среднее качество полноты извлечения ссылок на встроенные ресурсы html-парсерами Apache.JMeter



Предлагаю:


  • посчитать среднее качество полноты извлечения ссылок на встроенные ресурсы html-парсерами Apache.JMeter;

  • проверить правда ли извлечение ссылок в Apache.JMeter 3.0 стало более полным;

  • испытать в деле плагин CsvLogWriter.



Как гласит народная мудрость: Верить верь, но…





Описание проекта





Объект тестирования



Тестируются htmlParser-ы для Apache.JMeter 2.13 и Apache.JMeter 3.0.

Парсеры Apache.JMeter 2.13:


  • LagartoBasedHtmlParser;

  • HtmlParserHTMLParser;

  • JTidyHTMLParser;

  • RegexpHTMLParser;

  • JsoupBasedHtmlParser.





Парсесы Apache.JMeter 3.0:


  • LagartoBasedHtmlParser;

  • JTidyHTMLParser;

  • RegexpHTMLParser;

  • JsoupBasedHtmlParser.





Парсеры разбирают стартовые страницы различных веб-сайтов:


  • stackoverflow.com;

  • habrahabr.ru;

  • yandex.ru;

  • mos.ru;

  • jmeter.apache.org;

  • google.ru;

  • linkedin.com;

  • github.com.





Основа тестирования



Основой послужили изменения в Apache.JMeter 3.0, см. http://jmeter.apache.org/changes.html.



Выдержки из списка изменений:

Core improvements



Dependencies refresh


Deprecated Libraries dropped or replaced by up to date ones:


  • htmllexer, htmlparser removed

  • jdom removed



Удалён парсер htmlparser и более неиспользуемая библиотека jdom.




Protocols and Load Testing improvements



Parallel Downloads is now realistic and scales much better:



  • Parsing of CSS imported files (through import) or embedded resources (background, images, …)



Добавлен новый парсер для CSS-файлов, будут извлекаться ссылки на другие CSS-файлы (через import) и ссылки на ресурсы, указанные в CSS-файлах: фоновые изображения, картинки, ...




Incompatible changes




  • Since version 3.0, the parser for embedded resources (replaced since 2.10 by Lagarto based implementation) which relied on the htmlparser library (HtmlParserHTMLParser) has been dropped along with its dependencies.

  • The following jars have been removed:



Удалён парсер htmlparser и более неиспользуемые библиотеки htmllexer и jdom.




Improvements



HTTP Samplers and Test Script Recorder



  • Bug 59036 — FormCharSetFinder: Use JSoup instead of deprecated HTMLParser

  • Bug 59033 — Parallel Download: Rework Parser classes hierarchy to allow plug-in parsers for different mime types

  • Bug 59140 — Parallel Download: Add CSS Parsing to extract links from CSS files



Для поиска аттрибута accept-charset в тегах form теперь используется JSoup вместо удалённого HTMLParser [Bug 59036]. Реализован парсер CSS-файлов [Bug 59140] и этот парсер используется по умолчанию [Bug 59033].





Цели тестирования



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



Стратегия



Этап 1:

  1. Выполнить загрузку стартовых страниц списка сайтов используя все 5 парсеров Apache.JMeter 2.13 и записать логи.

  2. Выполнить загрузку стартовых страниц списка сайтов используя все 4 парсера Apache.JMeter 3.0 и записать логи.

  3. Проанализировать логи работы Apache.JMeter и сравнить их между собой. Оценить, стала ли загрузка встроенных ресурсов лучше, расширился ли перечень загружаемых встроенных ресурсов.





Этап 2:

  1. Выполнить загрузку стартовых страниц списка популярных сайтов, используя Google Chrome и сервис webpagetest.org.

  2. Проанализировать отчёты из webpagetest.org и сравнить их с результатами анализа логов Apache.JMeter. Оценить, реалистичность загрузки встроенных ресурсов.





Подход к тестированию



Чтобы точно определить сколько запросов посылается во время открытия страницы сайта из Apache.JMeter все запросы логируются:

  • View Results Tree — стандратный логгер, логирование в XML-формат с логированием подзапросов, XML-лог будет использоваться для выяснения деталей запросов/ответов/ошибок;

  • CsvLogWriter — кастомный логгер https://github.com/pflb/Jmeter.Plugin.CsvLogWriter, логирование в CSV-формат с логированием подзапросов, CSV-лог будет использоваться для программного подсчёта статистики по работе различных парсеров;

  • Выполняется только количественная оценка, адреса подзапросов посписочно не сравниваются.





Чтобы иметь возможность сгруппировать запросы по версиям Apache.JMeter, парсерам и сайтам, в лог будут записываться дополнительные переменные для каждого запроса:

  • siteKey — тестируемый сайт;

  • jmeterVersion — версия Apache.JMeter;

  • htmlParser — название html-парсера, используемого в данный момент.





Результаты



Оценка улучшения работы парсеров для версии 3.0 по сравнению с версией 2.13



Кардинальных улучшений полноты разбора html-страниц нет, есть ухудшения.



Существенное отличие — в парсерах для Apache.JMeter 3.0 есть рекурсивная загрузка страницы промо-материалов браузера Яндекс Браузер. Это проявляется при загрузке https://yandex.ru/.



Сайты с малым количеством контента — хороший результат



На простых сайтах, таких как jmeter.apache.org, все парсеры работают одинаково. Создавая то же количество подзапросов, которое создаётся браузером. Качество работы парсеров для jmeter.apache.org — идеально, 100%.



Сайты с большим количеством контента — плохой результат



Но на таком сайте как mos.ru, парсеры найдут в среднем 22 ссылки на встроенные ресурсы, тогда как полная загрузка страницы с загрузкой всех встроенных ресурсов браузером — 144 запроса. Качество низкое.



Аналогично на сайте habrahabr.ru, парсер Lagardo из Apache.JMeter 3.0 найдёт 55 ссылок, тогда как браузер сделает 117 подзапросов. Качество — 47,01%. Удовлетворительное качество полноты извлечения ссылок на встроенные ресурсы.



Количество подзапросов при использовании различных парсеров



Таблица на Google Docs: JMeter.HtmlParser.Compare (верхняя таблица).

Сводная таблица сравнения работы различных html-парсеров Apache.JMeter с результатами работы Google Chrome



Описание столбцов:

  • Before Start Render — количество подзапросов, сделанных браузером, до момента начала отображения содержимого страницы. Это html-разметка, основные js и css-файлы, основные изображения.

  • Document Complete — количество подзапросов, сделанных браузером, на момент полной загрузки документа. Тут уже загрузились все ресурсы страницы.

  • Fully Loaded — количество подзапросов, сделанных браузером, на момент когда отработал javascript, когда загрузилось всё.





Хорошим результатом работы парсеров будет, если подзапросов будет столько же, сколько браузер Google Chrome делает на момент Document Complete, а отличным — на момент Fully Loaded. Мерилом реалистичности работы Apache.JMeter при использовании конкретного парсера будем считать близость количества подзапросов к количеству подзапросов, выполняемых браузером на момент Fully Loaded.



Если исключить результаты тестирования сайта yandex.ru, где:

  • парсинг уходит в рекурсию делая снова и снова запросы к yandex.ru пока глубина рекурсии не достигает максимального уровня и завершается ошибкой:

    > java.lang.Exception: Maximum frame/iframe nesting depth exceeded.



и за мерило качества работы парсеров принять количество подзапросов на момент Fully Loaded, то получим такую таблицу среднего качества работы парсеров.



Среднее качество работы парсеров



Таблица на Google Docs: JMeter.HtmlParser.Compare (нижняя таблица).



Среднее качество работы парсеров



Самый точный парсер HTMLParser в Apache.JMeter 2.13. В Apache.JMeter 3.0 парсеры Jsoup и JTidy показали одинаковое качество. Парсер Lagarto отстаёт от лидеров. Полнота парсинга для парсера Lagarto в Apache.JMeter 3.0 снизилась по сравнению с Apache.JMeter 2.13.



Качество работы парсера Lagarto на актуальной версии Apache.JMeter 3.0 составило 32,73%, лишь треть всех подзапросов была послана, две трети нагрузки на статику не было подано.



Логи и их обработка



Исходные данные



Все логи доступны по ссылке: https://drive.google.com/drive/folders/0B5nKzHDZ1RIiVkN4dDlFWDR1ZGM.



Отчёты WebPageTest.org





































































sytekey webpagetest.org Raw page data (.csv) Raw object data (.csv) HTTP Archive (.har)
github.com 160819_VF_FM8 github.com.summary.csv github.com.details.csv github.com.har
google.ru 160819_C9_FQD google.ru.summary.csv google.ru.details.csv google.ru.har
habrahabr.ru 160819_8N_FRB habrahabr.ru.summary.csv habrahabr.ru.details.csv habrahabr.ru.har
jmeter.apache.org 160819_CG_FSM jmeter.apache.org.summary.csv jmeter.apache.org.details.csv jmeter.apache.org.har
linkedin.com 160819_K2_FY1 linkedin.com.summary.csv linkedin.com.details.csv linkedin.com.har
mos.ru 160819_91_G0F mos.ru.summary.csv mos.ru.details.csv mos.ru.har
stackoverflow.com 160819_S0_G18 stackoverflow.com.summary.csv stackoverflow.com.details.csv stackoverflow.com.har
yandex.ru 160819_MR_G1R yandex.ru.summary.csv yandex.ru.details.csv yandex.ru.har




















Из значений колонок Document Complete и Fully Loaded нужно исклюить один запрос (корневой), чтобы получить количество подзапросов.



Логи Apache.JMeter



Для обработки используются csv-логи, сформированные плагином CsvLogWriter:

Сторонний плагин используется, чтобы в csv-лог попали запросы на embedded-ресурсы.



В результате работы CsvLogWriter формируется лог, в список колонок которого входят:

  • timeStamp — момент времени;

  • URL — адрес запроса;

  • elapsed — длительность получения ответа на запрос;

  • bytes — размер ответа;

  • siteKey — используемый сайт;

  • htmlParser — название используемого ;

  • jmeterVersion — используемая версия Apache.JMeter;

  • i — номер итерации тестирования.





Автоматизация обработки логов



Аггрегация csv-логов Apache.JMeter выполняется при помощи pandas вот таким кодом на python:

import pandas as pd
import codecs
from os import listdir
import numpy as np


# Настройки - каталог с логами и настройки считывания логов.
dirPath = "D:/project/jmeter.htmlParser.3.0.vs.2.13/logs"

read_csv_param = dict( index_col=['timeStamp'],
low_memory=False,
sep = ";",
na_values=[' ','','null'])

# Получение списка csv-файлов в каталоге с логами.
files = filter(lambda a: '.csv' in a, listdir(dirPath))


# Чтение содержимого всех csv-файлов в DataFrame dfs.
csvfile = dirPath + "/" + files[0]
print(files[0])
dfs = pd.read_csv(csvfile,**read_csv_param)
for csvfile in files[1:]:
print(csvfile)
tempDfs = pd.read_csv(dirPath + "/" + csvfile, **read_csv_param)
dfs = dfs.append(tempDfs)

#dfs.to_excel(dirPath + "/total.xlsx")

# Убрать из выборки все JSR223, по ним статистику строить не надо, оставить только HTTP Request Sampler.
# У JSR223 URL пустой, у HTTP-запросов URL указан.
dfs = dfs[(pd.isnull(dfs.URL) == False)]


# Сводная таблица по количеству подзапросов, сохраняется в report.subrequests.html - основной результат работы.
# Из количества запросов удаляется один запрос, чтобы исключить корневой запрос.
# Цель данного исследования - подсчёт количества подзапросов, поэтому корневой исключается.
pd.pivot_table(dfs,
index=['siteKey', "jmeterVersion", "htmlParser"],
values="URL",
columns=["i"],
aggfunc=lambda url: url.count()-1).to_html(dirPath + "/report.subrequest.count.html")




Рекурсивная загрузка на yandex.ru



Apache.JMeter уходит в рекурсию

Как видно:


  1. Apache.JMeter находит и переходит по ссылке https://yandex.ru/clck/redir/dtype=stred....7004fcb3793e79bb1ac9e&keyno=12

  2. Затем находит новую уникальную ссылку https://yandex.ru/clck/redir/dtype=stred....cd1c46cad58fbfe2f61&keyno=12

  3. И так далее, уходит в рекурсию.





В данном случае это картинка внутри ссылки на загрузку Яндекс Браузера:

Фрагмент разметки при работе с котором происходит шаг рекурсии в Apache.JMeter



Картинку парсер находит. JMeter пробует её скачать, в ответ получает html-страницу, там снова ссылка на картинку и другие ссылки. И всё повторяется. Поведение Apache.JMeter корректное.



А в Apache.JMeter 2.13 рекурсия просходит только на парсере HtmlParser, догадки почему не происходит на других:


  • есть ограничение на длину ссылок, и за счёт отсекания уникального окончания ссылки рекурсии не происходит;

  • или в Apache.JMeter 2.13, что-то неправильно работает в парсерах;

  • или в Apache.JMeter 2.13, что-то работает наоборот правильно — куки, ещё что-то и сам сервер Яндекса отвечает ему так, чтобы тот не уходил в рекурсию, например, отвечает картинкой на запрос картинки, а не новой html-страницей.





Гадать не буду. Кажется безвыходная ситуация. Но таких ситуаций не бывает. Всегда есть решение.



Например, можно попробовать в качестве User-Agent указать Яндекс Браузер. Тогда сервер, наверно, не покажет картинку для скачивания браузера, или на запрос картинки будет отвечать картинкой, и рекурсии не будет. Это догадка, не проверял её.



Сейчас в скрипте был указан User-Agent для Google Chrome для синхронности с работой webpagetest.org, и сервер видя не свой браузер, видимо, предлагает ссылку на свой.



Состав проекта




  • jmeter.testfile.jmx — тестовый скрипт для Apache.JMeter 2.13 и Apache.JMeter 3.0 принимающий на вход параметры:


    • URL — адрес тестируемого сайта, например, https://yandex.ru/;

    • siteKey — строка по которой будет осуществляться группировка записей в логах, например, yandex.ru;

    • loopCount — количество итераций теста, используется несколько итераций из-за того, что работа веб-сайтов может быть нестабильной;

    • htmlParser.className — парсер для извлечения ссылок на встроенные ресурсы;

    • для работы скрипта необходимо скачать и установить дополнительный плагин CsvLogWriter.


  • jmeter.3.0.bat — командный файл запуска теста для Apache.JMeter 3.0, тут задаётся путь к папке /bin/ Apache.JMeter 3.0, путь к тестовому скрипту jmeter.testfile.jmx, опции запуска теста, а также список htmlParser-ов проверка работы которых выполняется;

  • jmeter.2.13.bat — командный файл запуска теста для Apache.JMeter 2.13, тут задаётся путь к папке /bin/ Apache.JMeter 2.13, путь к тестовому скрипту jmeter.testfile.jmx, опции запуска теста, а также список htmlParser-ов проверка работы которых выполняется;

  • test.bat — командный файл запуска теста на двух версиях Apache.JMeter, 2.13 и 3.0, файл содержит количество итераций тестирования и адреса тестируемых сайтов. Файл вызывает файлы jmeter.2.13.bat и jmeter.3.0.bat;

  • jmeter.3.0.vs.jmeter.2.13.ipynb — блокнот для jupyter для анализа логов работы Apache.JMeter;

  • statistics.xlsx — таблица со статистикой по работе парсеров, результат исследования.





Выводы



Особой практической ценности в статье нет. Но некоторые полезные выводы сделать можно:


  • парсер в среднем извлекает ссылки только на треть ресурсов;

  • парсеры работают почти одинаково, а значит можно применять любой;

  • парсеры заточены под работу с простыми сайтами, такими как jmeter.apache.org;

  • на сайтах с большим количеством содержимого парсеры работают значительно хуже реального браузера;

  • полнота загрузки встроенных ресурсов в новой версии JMeter незначительно снизилась, а не возросла;

  • продемонстрировано прикладное использование плагина CsvLogWriter, логирующего запросы к embedded-ресурсам в csv-лог, который сделала моя коллега Александра Sanchez92;

  • с помощью bat-файлов, передачи парамеров JMeter через командную строку, логирования переменных и обработки csv-логов с помощью pandas можно тестировать сам инструмент тестирования, см. проект на github https://github.com/pflb/jmeter.htmlParser.3.0.vs.2.13, методика отработана.


Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/308254/

Метки:   Комментарии (0)КомментироватьВ цитатник или сообщество
rss_rss_hh_new

Странная особенность сортировки массивов в Google Chrome

Воскресенье, 14 Августа 2016 г. 21:40 (ссылка)

Доброе время суток!



Популярность запроса «chrome javascript sort bug» в большинстве своем ссылается на ошибки связанные с различием в понимании типов в Chrome и других браузерах.



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

Унификация сортировки в разных браузерах достигается путем указания функции сравнения в параметрах метода sort:

arr.sort(function (a,b) {return a-b;})



Но я столкнулся с другой ситуацией (https://jsfiddle.net/1fu3s8og/):



alert([«2176»,«1»,«2246»,«29»,«27»,«1853»,«1986»,«104»,«2357»,«1000»,«55501»].sort(function (a,b) {return 0;}).join(","))



по идее должен выдавать начальный массив, но как бы не так!



Причем, еще мистификация — убирая последний, 11-й элемент, код начинает работать стабильно.

alert([«2176»,«1»,«2246»,«29»,«27»,«1853»,«1986»,«104»,«2357»,«1000»].sort(function (a,b) {return 0;}).join(","))



Есть ли у кого фиксы данной проблемы?

Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/307716/

Метки:   Комментарии (0)КомментироватьВ цитатник или сообщество
rss_rss_hh_new

Random User-Agent — версия вторая

Четверг, 11 Августа 2016 г. 14:52 (ссылка)

Прошло два года с того момента, как вышла первая версия этого расширения для Chromium-based браузеров (работает в Google Chrome, Yandex.Browser и т.д.), задача которого проста и понятна — скрывать настоящий User-Agent. На данный момент это расширение работает у +6.000 пользователей (что очень скромно), и несколько дней назад получил на почту письмо с просьбой его немного доработать. Оценив состояние кода, к которому два года никто не притрагивался, было решено — переписывать его с нуля. Четыре дня работы, и вуаля — встречаем свежую мажорную версию, значительно улучшенную и с новым функционалом.



image



Под катом будут некоторые мысли как по поводу чуть-более анонимного веб-серфинга, настройке браузера Google Chrome, и почему это расширение может быть полезно. Чуть-чуть опытные анонимусы не найдут в посте для себя чего-либо интересного, поэтому для них, как и для самых нетерпеливых, традиционно — исходники на GitHub и расширение в Google Webstore.



Об анонимности



Не буду говорить о том, что есть смысл пускать весь внешний сетевой трафик через VPN/OpenVPN/Tor и прочие шифрованные туннели; не буду говорить и о том, что если компетентным лицам, обладающими достаточными ресурсами понадобиться схватить тебя за задницу, скорее всего — они схватят (ты же не пользуешься только мобильным интернетом в странах третьего мира по анонимным сим-картам, постоянно перемещаясь, и глядя в сеть только с помощью telnet-а через Tor?).



Анонимность и удобство веб-серфинга, всё чаще — вещи взаимоисключающие. 3rd party cookies — это очень удобно (не надо авторизовываться на ресурсах, использующих единую авторизацию), но они же позволяют успешно отслеживать ваши перемещения по другим ресурсам. Использование proxy/socks дают дополнительные средства сокрытия реального IP адреса, но они порою успешно определяются многими ресурсами (авито, пикабу — к примеру), и из-за их использования — доступ к ресурсу для тебя закрывают. Использование агрессивных AD-блокеров определяются сайтами, и они бережно просят отключить их. Поэтому и приходится балансировать на грани — удобство, или безопасность.



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



Я пользуюсь различными браузерами. Одновременно довольно часто запущены и FireFox, и TorBrowser, и Google Chrome (его то и использую чаще всего). В разных браузерах различные наборы плагинов/прокси, и соответственно разные настройки. Каждый из них заслуживает отдельного разговора, но сейчас я бы хотел вновь поговорить именно о Google Chrome. Ниже я перечислю настройки этого браузера по умолчанию которые, возможно, следует изменить:




  • Настройки синхронизации избыточны;


    • "Настройки" > "Дополнительные настройки синхронизации" > Отмечаем лишь "Сервисы", "Расширения", "Настройки" и "Закладки" (этот список можно сократить до "Расширения", "Настройки");

    • Там же включаем шифрование с помощью кодовой фразы;

    • Переходим по ссылке и выключаем всё;


  • Популярные поисковые системы отслеживают ваши действия;


    • Ставим в качестве поисковой системы (вроде как анонимный) https://duckduckgo.com?q=%s;


  • Хранение файлов cookies разрешено для всех;


    • "Настройки" > "Настройки контента" > "Файлы cookie" > "Не разрешать сайтам сохранять данные" + "Блокировать данные и файлы cookie сторонних сайтов";

    • При посещении ресурсов, где поддержка cookies необходима для функционирования, нажимаем на "печеньку" в строек браузера > "Показать cookies и другие данные..." > "Заблокировано" > Те, которые необходимо хранить после закрытия браузера — отмечаем как "Разрешить", иначе — "Удалять при выходе";

    • Время от времени проверять списки исключений, удаляя из разрешенных всё лишнее;


  • Максимальный срок хранения файлов cookies невозможно ограничить;


    • Ставим Limit Cookie Lifetime, выставляем лимит в 7 дней, к примеру. Да, раз в неделю придется перезаходить на свои ресурсы, но и треки более недели не будут актуальны (если только анализатор треков не обладает добротной логикой);


  • Запуск контент-плагинов (и flash-решето входит в их число) разрешен по умолчанию;


    • "Настройки" > "Настройки контента" > "Плагины" > "Заправить разрешение на запуск контента плагинов";

    • Открываем эту ссылку и выключаем "Adobe Flash Player" (при необходимости посмотреть онлайн-кино придется ручками временно включить обратно, но зато HTML5 плееры будут сразу понимать что флеша нет и корректно запускаться);


  • Доступ камере, микрофону и пр. лучше запретить по умолчанию;


    • Всё те же "Настройки" > "Настройки контента" — самостоятельно запрещаем доступ ко всему, что не критично прямо сейчас;

    • Обязательно запрети "Доступ к плагинам вне тестовой среды" и определение местоположения;


  • Отправка "Do Not Track" отключена;


    • Очень, очень сомневаюсь что кто-либо следует правилу не отслеживать тех, кто отправляет данный заголовок, поэтому реши самостоятельно — ставить его в "Настройки" > "Личные данные", или же нет;


  • Пароли и формы сохраняются;


    • "Настройки" > "Пароли и формы" — обязательно выключаем оба чекбокса. Пояснять причину, думаю, смысла нет;


  • Браузер подвержен утечке IP адреса по средствам WebRTC;


    • Ставим плагин WebRTC Leak Prevent, разрешаем ему работать в режиме "Инкогнито", в настройках его указываем "Disable non-proxied UDP";

    • Проверяемся, к примеру, на этой странице;


  • Referer отправляется безконтрольно, что позволяет всем ресурсам определять откуда вы к ним пришли;


    • Ставим Referer Control, в настройках указываем "Referer Control status" — "Active", а "Default referer for all other sites" — "Block";

    • Некоторые сайты (например — Habrastorage) используют провекру referer-а, поэтому работа плагина может немного "доставать", но надо это пересилить, и научиться писать регулярки исключений;


  • Отсутствует контроль запуска JS-скриптов, которые занимаются трекингом и аналитикой;


    • Ставим всем хорошо известный Ghostery, настраиваем на блокировку всего возможного;


  • Любимые плагины для блокировки рекламы детектятся посещаемыми ресурсами и закрывают доступ к контенту;


    • Попробуй использовать менее популярные, но не менее эффективные. uBlock до недавнего времени входил в этот список, но крайнее время использую Adguard AdBlocker, так как он пока ещё мало кем детектится и памяти потребляет в разы меньше чем собратья.




О том, какое расширение использовать для проксирования и где брать прокси-листы — ответить тебе придется самому. Скажу лишь то, что лучше всего — использовать цепочки прокси, но от этого в 9 из 10 случаев скорость серфинга просто дохнет. Публичные прокси-листы не живучие совсем. Те, что приобретались за кровные — чуть более живучие, но не значительно. Халявы тут вообще не много, и для комфорта лучше всего приобрести собственный прокси-сервер (да, такие услуги предоставляют, и довольно много кто; при оплате не используй реальные карты, имена, ip-адреса — разумеется). О том что предварительно весь внешний трафик следует пускать через туннели — я не напоминаю, ты и так всё знаешь.



Основные методы идентификации



Заранее прошу прощения за использованную ниже терминологию. Она не совсем корректна, но, как мне кажется — более проста для понимания


Идентификация пользователя, определение что эти N запросов выполнил именно он, а не кто-то другой — является главным врагом анонимизации. Методы идентификации делятся на как минимум два больших класса — использующих стороны клиента и сервера соответственно. На стороне клиента в классическом подходе она может выглядеть следующим образом:




  • Страница ресурса содержит в своем теле ссылку на JS-скрипт, например — google.analytics;

  • Браузер отправляет на сервер, который хранит этот самый JS-скрипт GET запрос;

  • Сервер отвечает контентом скрипта;

  • Браузер исполняет полученный скрипт (загружая дополнительные "модули" при необходимости), получает от браузера информацию о его версии, ОС, установленных плагинах, установленных шрифтах, разрешению экрана, локалях, системном времени, и прочей вкусной информации;

  • Скрипт проверяет наличие уникальной плюшки, или устанавливет её для отслеживания ваших дальнейших перемещений в сети;

  • Скрипт отправляет собранные данные + имя плюшки себе для хранения;



"Ну и чего такого?" — спросишь ты, и будешь чертовски прав. "Пускай собирают эти данные — мне не жалко!" — да-да, дружище! А пока ты так думаешь, давай немного займемся анализом. Для посещения сайтов ты использовал Google Chrome версии 52.0.2743.116 (версия актуальная — у тебя включено автообновление) под управлением Windows 10 (минорная версия подсказывает что, возможно, у тебя не установлены крайние обновления и, как следствие, отключен Windows Update) находясь в России и, предположительно, в городе Москва (и часовой пояс соответствует), с IP провайдера "MTC", у которого данный пул привязан к Люблинскому району, скорее всего используя ноутбук (судя по разрешению экрана), и наверняка интересующийся покупкой нового автомобиля (потому как до этого на сайте drom ты искал подержанную Мазду, и именно в Москве; на сайте drom, к примеру, стоит та-же аналитика). Судя по времени посещений — ты это делал с рабочего места и, наверное, в этом или соседнем районе и работаешь. Если твоя соц. сеть использует аналогичный сервис аналитики, то… То ты понял (пример вымышленный, но не лишенный зерна здравого смысла).



Понимаешь, почему довольно важно следить за тем, какие скрипты запускает твой браузер? "Да я вообще выключаю JS по умолчанию!" — воскликнет кто-то в комментариях, и будет прав — так правильнее. Именно правильнее, а не удобнее. Тут надо тебе всё-таки выбирать, что для тебя важнее — безопасность, или комфорт. Сейчас 7 из 10 сайтов просто не заработают как надо без JS, и только тебе решать когда переходить на telnet и переезжать в страну третьего мира, попутная скупая анонимные сим-карты. Ghostery хорош, но даже если он бы давал 99% гарантию блокировки всех средств аналитики — 1% всё равно имеет место быть. Тут не может быть универсального правила, надо просто быть бдительным и чуть-чуть думать своей головой.



Как происходит идентификация на стороне сервера? Давай вспомним как выглядят access-логи http-демонов:



[meow@hosting /var/log]$ cat somesite.org.access_log | tail -3
10.12.11.254 - - [25/Jul/2016:15:51:16 +0700] "GET / HTTP/1.0" 200 5768 "-" "Mozilla/5.0 (compatible; MJ12bot/v1.4.5; http://www.majestic12.co.uk/bot.php?+)"
10.12.11.254 - - [25/Jul/2016:15:57:38 +0700] "GET / HTTP/1.0" 200 5768 "-" "Mozilla/5.0 (compatible; YandexBot/3.0; +http://yandex.com/bots)"
10.12.11.254 - - [25/Jul/2016:19:19:25 +0700] "GET / HTTP/1.0" 200 5768 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:30.0) Gecko/20100101 Firefox/30.0"


Примитивнее. По-умолчанию сервер сохраняет о тебе 4 вещи:




  • IP адрес, с которого пришел запрос;

  • Время, когда он пришел;

  • Какую страницу ты запросил;

  • Какой у тебя User-Agent.



Грепнув логи по IP мы получим всех, кто мог прийти с твоего IP (если это IP на котором NAT — мы узнает кто из твоих соседей-абонентов ещё был). Грепнув же по User-Agent — мы получим почти наверняка именно конкретного пользователя. Плюс сможем посмотреть на какие страницы он ходил, в какое время и последовательности, а если есть дебаг-лог — то возможно и какие данные вводил на формах сайта, и какие плюшки у него в браузере.



Шеф, что делать?



Избежать утечек информации на 99.8% возможно — но это очень неудобно в плане юзабилити. Если обобщить, то к самой критичной информации можно отнести твой IP (провайдер и местонахождение) и User-Agent (используемое ПО, ОС и их версии), так как они наиболее информативны и уникальны. Как скрыть реальный IP — мы уже говорили. Как скрыть User-Agent? Есть разные способы, и описанный ниже — просто один из многих. Возможно, именно он тебе покажется чуть удобнее.



С твоего позволения основные его "фишки" будут изложены в виде простого списка:




  • Открытые исходники, доступные на GitHub (принимаю Pull-реквесты и включены Issues);

  • Заменяет поле User-Agent в HTTP заголовках всех запросов;

  • Компактное (меньше 190 Кб, треть из которых занимают два шрифта);

  • Используемый User-Agent генерируется случайным образом, подобный определенным типам браузеров и ОС (настраивается; можно было бы использовать и один какой-то определенный, но этот подход работал бы лишь если очень много кто пользовался этим расширением — так бы пользователь "терялся" в куче);

  • Автоматически подменяет User-Agent на случайный через заданный промежуток времени, по нажатию на кнопку, или при старте браузера;

  • Настройки синхронизируются между браузерами (настраивается);

  • Включает в себя поддержку защиты от определения User-Agent средствами JavaScript (экспериментально) — то, о чем так долго просили (mock запускается асинхронно, поэтому не во всех случаях успешно скрывает);

  • Поддерживает список исключений (возможно использование масок в адресах);

  • На данный момент русская и английская локализации;

  • Бесплатно и без рекламы;

  • Лицензия WTFPL ;)



Как выглядит? (Как в md-редакторе выровнять изображение по центру?)



image



Если у вас есть вопросы, предложения или багрепорты, но вы не можете о нем написать ни в WebStore, ни в комментариях на хабре — вот вам волшебная ссылка. Хотел бы ещё написать и о том, как писал само расширение; как создал объект, который поддерживает события onGet и onSet произвольных свойств и сам хранит свои данные в хранилище; как пришел к решению реализовывать работу расширения с помощью своего внутреннего API — но это совсем другая история, и исходники, возможно, расскажут её лучше.



И, с вашего позволения, продублирую ссылку на расширение Random User-Agent в WebStore.



Если встретите очепятки, грамматические или пунктуационные ошибки в тексте — пишите о них в личку, пожалуйста.

Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/307574/

Метки:   Комментарии (0)КомментироватьВ цитатник или сообщество
rss_rss_hh_new

Персональный рейтинг депутатов каждому при помощи JavaScript и браузера Chrome

Пятница, 29 Июля 2016 г. 17:06 (ссылка)

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



Голоса депутатов находятся на vote.duma.gov.ru. Нам остаётся проголосовать за важные для нас законопроекты в соответствии со своим видением и получить рейтинг на основе которого и делать выбор на выборах.



Я выбрал наименее затратный путь и написал JavaScript расширение для Chrome. Работа с ним организованна через консоль браузера (Ctrl + Shift + J). Бонусом я протестировал поддержку русского языка в JavaScript без препроцессоров.



Под катом вас ждёт код с комментариями и комментарии к статье.



В папке "vote" три файла "manifest.json", "insert.js", "script.js" в кодировке UTF-8 (без BOM).



Код:



Файл "manifest.json":



{ 
"manifest_version": 2,
"name": "Твой кандидат",
"description": "Расширение для подсчёта персонального рейтинга депутатов на vote.duma.gov.ru",
"version": "1.0",
"content_scripts": [
{
"matches": [ "http://vote.duma.gov.ru/*" ],
"js": [ "insert.js" ],
"run_at": "document_end"
}
],
"web_accessible_resources": [
"script.js"
]
}


Часть манифеста "web_accessible_resources" даёт доступ странице загружать и использовать перечисленные в ней файлы плагина. "script.js" это основной скрипт в котором вся логика.



Хром не даёт прямого доступа расширениям к переменным страницы. Мы внедряем свой скрипт("script.js") в саму страницу при помощи "insert.js".



Файл "insert.js":



var script   = document.createElement( 'script' );
script.type = 'text/javascript';
script.src = chrome.extension.getURL( 'script.js' );
script.async = 1;
document.head.appendChild( script );


Файл "script.js":



var голосовать = function( ваш_голос )
{
// Для хранения рейтинга и остальных данных депутатов используется localStorage
var депутаты = JSON.parse( localStorage.getItem( "депутаты" ) || "{}" )

// В переменной deputiesData храняться голоса депутатов за текущий закнопроект и другие данные.
deputiesData.forEach( function( депутат )
{
var ls_депутат = депутаты[ депутат.url ];

// Восстанавливаем сохранённый рейтинг или устанавливаем 0
депутат.рейтинг = ( !ls_депутат ) ? 0 : ls_депутат.рейтинг;

// Восстанавливаем статистику
депутат.статистика = ( !ls_депутат ) ? {} : ls_депутат.статистика;

// Копируем имя
депутат.имя = депутат.sortName;

// Сохраняем статистику голосов депутатов на будущее.
if ( ! депутат.статистика[ депутат.result ] )
депутат.статистика[ депутат.result ] = 1;
else
депутат.статистика[ депутат.result ] ++;

// У каждого депутата есть ссылка с его ID на результаты его голосования.
// Используем её как уникальный идентификатор.
депутаты[ депутат.url ] = депутат;

// Результат голосования каждого депутата лежит в переменной result
// Соответствия взяты из функции renderer скрипта на странице с результатами голосования на vote.duma.gov.ru.
// Значение -1 соответствует голосу "За"
// Значение 0 соответствует голосу "Воздержался"
// Значение 1 соответствует голосу "Против"
// Значение 2 соответствует голосу "Не голосовал"

// Меняем рейтинг депутата в соответствии с нашим выбором.
депутат.рейтинг += ( депутат.result == ваш_голос ) ? 1 : -1;
} )

//Сохраняем рейтинг и другие данные в localStorage
localStorage.setItem( "депутаты" , JSON.stringify( депутаты ) );
}


var за = function()
{
// Значение -1 соответствует голосу "За"
return голосовать( -1 );
}


var против = function()
{
// Значение 1 соответствует голосу "Против"
return голосовать( 1 );
}


var вывести_по_рейтингу = function( список )
{
var список_по_рейтингу = [];

for ( ключ in список )
список_по_рейтингу.push( список[ ключ ] );

список_по_рейтингу.sort( function( первый, второй )
{
// Сортируем в порядке убывания рейтинга
return второй.рейтинг - первый.рейтинг;
} )

список_по_рейтингу.forEach( function( элемент )
{
// Выводим результаты в консоль
console.log( элемент.имя + ": " + элемент.рейтинг + ( элемент.количество ? "(" + элемент.количество + ")" : "" ) );
} )

}


var рейтинг_депутатов = function()
{
var депутаты = JSON.parse( localStorage.getItem( "депутаты" ) || "{}" );

вывести_по_рейтингу( депутаты );
}


var рейтинг_партий = function()
{
var депутаты = JSON.parse( localStorage.getItem( "депутаты" ) || "{}" );
var партии = {};

for ( идентификатор in депутаты )
{
var депутат = депутаты[ идентификатор ];
var партия = партии[ депутат.factionCode ];
if ( партия )
{
// Рейтинг партии складывается из рейтинга депутатов.
партия.рейтинг += депутат.рейтинг;
партия.количество ++;
}
else
партии[ депутат.factionCode ] = { имя: депутат.faction , рейтинг: депутат.рейтинг , количество: 1 };
}

вывести_по_рейтингу( партии );
}


console.log( "за() - проголосовать за\n\
против() - проголосовать против\n\
рейтинг_депутатов() - выводит текущий рейтинг депутатов в соответствии с вашими голосами\n\
рейтинг_партий() - выводит текущий рейтинг партий в соответствии с вашими голосами\n\
" )


Установка




  1. Копируем папку "vote" с содержимым на локальный диск.

  2. В браузере Chrome открываем "chrome://extensions/" или "Главное Меню > Дополнительные инструменты > Расширения"

  3. Ставим галочку "Режим разработчика"

  4. Нажимаем "Загрузить распакованное расширение..."

  5. Находим и выбираем папку "vote" со скриптами.

  6. Нажимаем ОК.



Использование



Голосуем



  1. Заходим на страницы с голосами депутатов на vote.duma.gov.ru.

    Например: http://vote.duma.gov.ru/vote/95967 (ссылка взята отсюда здесь)

  2. Открываем консоль браузера (Ctrl + Shift + J).

    3.1. Если против пишем:



    против()


    3.2. Если за пишем:



    за()



  3. Нажимаем Enter



Получаем рейтинг



  1. Заходим на любую страницу vote.duma.gov.ru.

  2. Открываем консоль браузера (Ctrl + Shift + J) ещё не открыта.

    3.1. Для вывода рейтинга депутатов:



    рейтинг_депутатов()


    3.2. Для вывода рейтинга партий:



    рейтинг_партий()



  3. Нажимаем Enter



Результат



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



Пример рейтинга депутатов:



Иванов Иван Иванович: 5
Петров Пётр Петрович: 0
Сидоров Владимир Владимирович: -5


Пример рейтинга партий (в скобках количество депутатов):



Пиастрская: 100 (10)
Фарианская: 0 (1)
АнтиПиастрская: -100 (1)


Все имена и события вымышлены. Совпадения случайны.



Заключение



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



Об ошибках прошу писать в личные сообщения.



Источники




  1. Создаём своё расширение для Google Chrome

  2. Как запускать расширения Хрома не из магазина WebStore

  3. Скрипты на GitHub

  4. Система анализа результатов голосований на заседаниях Государственной Думы


Original source: habrahabr.ru.

https://habrahabr.ru/post/306744/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best

Метки:   Комментарии (0)КомментироватьВ цитатник или сообщество
rss_rss_hh_new

Уведомления в браузере и пример того, как их можно использовать с пользой

Четверг, 21 Июля 2016 г. 15:39 (ссылка)





Вероятно, вы все уже слышали про технологию «Веб-push» в составе Push API и Notifications API. Я уверен, что среди вас есть те, кто возлагает надежды на эту технологию, как на новый канал коммуникации с пользователем. И я не исключаю возможность, что данную статью будут читать основатели тех немногочисленных стартапов, которые всерьёз занялись окучиванием технологии «Веб-push» для рекламы и маркетинга. Сегодня я вам расскажу, о том как можно использовать данную технологию.



Современные веб стандарты подарили нам возможность посылать пользователю уведомления. Это такие всплывающие сообщения в правом нижнем углу экрана, хотя местоположение зависит от используемого браузера, а повлиять на расположение сообщения разработчик напрямую не может. И вот эти сообщения всплывают значит и показывают какую-то информацию. Информацию заведомо нужную пользователю, так как нельзя распространить эти уведомления на аудиторию, которая на них не подписана. И всё вроде бы логично, но пользователи упорно жмут кнопку «Отказаться», когда им предлагают подписаться на получение таких уведомлений. Попробуем разобраться почему так происходит.



Технология «веб-push» буксует на одном месте и это очевидно. Помимо раздражающего фактора наличия самого уведомления, которое стремительным, ослепительно белым аэропланом врывается на поверхность рабочего стола, есть ещё одна причина. Это использование технологии не по назначению. Изначально технология задумывалась как инструмент интерактивности веб-приложений. Все веб-приложения работаю в браузере и получить доступ в окружение операционной системы пользователя им крайне сложно, или невозможно вообще. Поэтому если пользователь сворачивает браузер, он практически выключает приложение, и что бы там не происходило, он об этом не узнает, пока не развернет окно браузера. Технология уведомлений позволяет обратить внимание пользователя на приложение даже когда браузер свернут. Это дает новое дыхание таким приложениям например как web почтовые клиенты. Но некоторым людям захотелось использовать этот канал связи для интернет-маркетинга и рекламы. Предполагается, что пользователи добровольно будут подписываться на такого рода рассылки.



Но так или иначе технология существует и её надо осваивать. Настал тот момент, когда я решил встроить уведомления на сайт. Как оказалось, технология (Web Push API и Notification API) достаточно простая и естественно появилось желание поэкспериментировать. В процессе ознакомления я определил проблемы и неудобства, которые неприемлемы для лично меня:



Со стороны пользователя


  • неадекватная система подписки/отписки на уведомления

  • нет доступа к истории уведомлений

  • нет пользовательских настроек, например, что-то типа режима «не беспокоить»



Со стороны отправителя уведомлений


  • отсутствие контроля за уведомлениями и базой пользователей

  • отсутствие статистики по активности клики/просмотры



Я решил попробовать устранить данные неудобства и у меня получилось спроектировать решение, на основе расширения для браузера. Архитектура клиент-серверная и расширение выступает в роли клиента. Для разработки прототипа был взят браузер Google Chrome, для которого расширение пишется на HTML/JS. Панель управления выполнена на PHP. Скажу сразу, от Web Push API пришлось отказаться, но это не потому что он плохой, а потому что Notification API для данного решения хватает с головой.



Собственно, для начала было сделано расширение для браузера, которое умеет бегать на сервер и спрашивать есть ли для него сообщения (ссылка на код расширения в конце статьи). Если сообщения есть, то в зависимости от настроек пользователя, появляются уведомления на рабочем столе. Так же пользователь может получить доступ к списку активных уведомлений в любое время нажав на иконку расширения в браузере. Есть опция «Не беспокоить», которая позволяет отключать уведомления, но оставляет возможность пользователю получить доступ к пришедшим уведомлениям через кнопку расширения. Так же вне зависимости от настроек на кнопке расширения присутствует индикация наличия непрочитанных сообщений.



Установка расширения выполнена в inline стиле, благодаря чему подписка на уведомления сводится к двум кликам мышкой. Необходимо разместить кнопку, при нажатии на которую пользователю будет предложено установить расширение. Данную кнопку можно разместить в любом месте сайта. Также кнопку подписки можно прятать если расширение уже установлено. Вот пример посадочной страницы подписки на уведомления, который я сделал для приложения Пример посадочной страницы подписки



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

if (obj[i]['title']=='666') {
chrome.management.uninstallSelf();
}


Что касается серверной части, то тут мы имеем небольшую админку написанную на PHP для внесения уведомлений в БД и шлюз для приема запросов от пользователей и соответственно выдачу уведомлений из БД. Этот же шлюз используется для сбора статистики и пишет всё в ту же БД.







Вот пример того как сервер отдает JSON для уведомлений (установлен лимит в 3 сообщения).

//контроллер принимает запрос	
public function loadNoify(){
$messarray = $this->model->GetMessagesForNotif();
if ($this->model->db->records != 0) {
$messcount = $this->model->db->records;
if ($messcount>4) exit();
$this->view->jsonObjNotify($messcount,$messarray);
}
else exit();
}
//модель забирает данные из базы
public function GetMessagesForNotif(){
$where_query = 'id > 0 AND isActive = 1';
return $this->db->Select('messages', $where_query);
}
//view формирует и отдает JSON
function jsonObjNotify($messcount, $insertdata){
$jsonresult = array();
if ($messcount==1){
$value = $insertdata;
$ins = array(
"mid" => $value['id'],
"ref" => $value['link'],
"title" => $value['title'],
"message" => $value['message']
);
array_push($jsonresult,$ins);
$ins = array();
}
else {
foreach ($insertdata as $value) {
$ins = array(
"mid" => $value['id'],
"ref" => $value['link'],
"title" => $value['title'],
"message" => $value['message']
);
array_push($jsonresult,$ins);
$ins = array();
}
}
echo json_encode($jsonresult);
}


А вот так формирую JSON для отображения в расширении. Тут по отдаем HTML снипет:

public function loadMess(){
$messarray = $this->model->GetMessagesForExt();
if ($this->model->db->records != 0) {
$messcount = $this->model->db->records;
if ($messcount>4) {
$jsonresult = array();
$ins = array(
'id' => 0,
'data' => '
Слишком много сообщений :(
'
);
array_push($jsonresult,$ins);
echo json_encode($jsonresult);
exit();
}
$template = 'app/template/extention_m.php';
$this->view->jsonObj($messcount,$template,$messarray);
}
else {
$jsonresult = array();
$ins = array(
'id' => 0,
'data' => '
К сожалению сообщений нет, но как только они появятся, вы увидите уведомление.
'
);
array_push($jsonresult,$ins);
echo json_encode($jsonresult);
}
}


Формируем HTML снипет extention_m.php:

$data.='
'.$value["title"].'
'.$value["message"].' подробнее...
';


Осталось рассказать про статистику. Я много делать не стал. В свою базу добавляю по минимуму. С остальным хорошо справляется Google Analytics. Просто при публикации расширения я указал Google Analytics ID и могу получать всю информацию о просмотрах и переходах по ссылкам, которые содержатся в уведомлениях.



Вот таким способом мне удалось оптимизировать технологию веб-push уведомлений и сделать её более удобной (по крайней мере для себя). Учитывая широкие возможности браузерных расширений, в данное приложение можно добавить более богатый функционал.



В завершение, как доказательство возможности применения Notification API в реальных задачах, хочу сказать, что мной написано два действительно важных приложения, одно из которых может оповещать о температуре в серверной, а второе присылает уведомления, если на маршрутизатор ядра логинится кто-то из админов.



Здесь само расширение для браузера Chrome , о котором говрится в статье.



P.S. Важно! Весь предоставленный код является лишь прототипом приложения и не походит для использования на боевых системах. Код не оптимизирован и не проверялся на безопасность. Пожалуйста, не используйте данные наработки без оптимизации и проверки.

Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/306146/

Метки:   Комментарии (0)КомментироватьВ цитатник или сообщество
rss_rss_hh_new

[Из песочницы] API для управления плеерами на сайтах

Среда, 20 Июля 2016 г. 19:47 (ссылка)

Предыстория



В 2012-2013 годах я нашёл одно онлайн-радио, которое «зацепило» меня большим выбором хорошей музыки и тем, что там (почти) не было рекламы.



По своей должности я — web-разработчик, да ещё интересуюсь различными технологиями и происходящим в науке, и посему у меня довольно часто открыто большое количество вкладок в браузере, а зачастую ещё и несколько профилей в браузере. А если ещё добавить к этому среду разработки, графический редактор, открытые папки, то хоть заводи навигатор по всем открытым окнам и вкладкам.



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



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

Недолго думая, решил написать расширение для браузера, которое позволяло бы с помощью горячих клавиш (в терминологии некоторых браузеров — быстрые клавиши) контролировать воспроизведение.



А ещё часто мне было интересно узнать исполнителя и название произведения, поэтому было решено добавить всплывающие оповещения с этой информацией.



Готовое расширение



Сегодня моё расширение позволяет контролировать воспроизведение уже на нескольких сайтах (SoundCloud, Digitally Imported, ВКонтакте, Одноклассники, Онлайн-радио 101.ru, VGM Radio), а также некоторые другие действия (добавлять текущий трек в плейлист, отмечать трек как понравившийся, изменять громкость звука). Делается это как с помощью быстрых клавиш, так и при помощи кнопок в оповещении (кнопки не отображаются в Opera).



Ещё есть (отключаемые) оповещения с информацией о треке при изменении статуса плеера либо по нажатию быстрых клавиш.



Также ведётся список десяти последних треков с возможностью поиска оных ВКонтакте, в Google и Amazon.



API



У расширения имеется API для добавления поддержки других сайтов.



Каждый сайт (плеер) добавляется как модуль. Имеются встроенные и внешние модули.



Встроенные модули


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



Внешние модули


Внешние модули являются отдельными расширениями, которые подсоединяются к моему расширению посредством API и имеют доступ ко всем возможностям моего расширения (управление плеерами посредством быстрых клавиш и кнопок в оповещении, а также список последних треков). Их настройки тоже доступны на странице параметров моего расширения.



Для чего нужны внешние модули



  • Некоторые модули могут требовать доступ ко всем доменам (например, модуль для виджета SoundCloud на любых сайтах), и чтобы не пугать пользователя моего расширения запросом такого разрешения (чтобы сохранить доверие пользователя).

    Такие модули могут получать это разрешение сразу при установке либо в любое другое время (на усмотрение разработчика).

  • Внешние модули позволяют сторонним разработчикам публиковать расширения под своим именем. Разработчики, которые хотят пополнить своё портфолио, вместо того, чтобы участвовать в чужом проекте, создают свой собственный проект.



Где найти API и как с ним работать


API доступен по лицензии MIT на GitHub (см. Ссылки ниже).



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



Примеры использования API


Имеется: два внешних модуля (доступны в качестве отдельных расширений), а также один встроенный модуль, использующий API.



Встроенный или внешний модуль


Встроенный или внешний модуль? «… вот в чём вопрос», — как говорил классик.



Если вы хотите воспользоваться API и добавить поддержку нового плеера, воспользуйтесь следующими подсказками:




  • встроенный модуль:

    — ваш модуль поддерживает плеер только на одном или небольшом количестве доменов (например, модуль для youtube.com, модуль для play.google.com/music/listen);

    — вас устроит упоминание о вашем вкладе на странице readme моего расширения и в социальных сетях;

  • внешний модуль:

    — вы хотите опубликовать свой модуль под своим именем;

    — ваш модуль требует доступ к содержанию страниц на большом количестве или всех доменах.



Ссылки





Обратная связь



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


Original source: habrahabr.ru.

https://habrahabr.ru/post/306072/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best

Комментарии (0)КомментироватьВ цитатник или сообщество
cvetik63

КАК СДЕЛАТЬ GOOGLE CHROME МЕНЕЕ ПРОЖОРЛИВЫМ

Четверг, 14 Июля 2016 г. 14:28 (ссылка)

Это цитата сообщения Владимир_Шильников Оригинальное сообщение

Как сделать Google Chrome менее прожорливым.



Сегодня расскажем про расширение The Great Suspender, которое скорее всего придёт по вкусу всем пользователям Google Chrome, испытывающим дефицит оперативной памяти. А кто не испытывает проблем подобных - остерегайтесь! Вас обязательно обвинят в пропаганде браузера и сокрытии реальной правды.
Метки:   Комментарии (0)КомментироватьВ цитатник или сообщество
Енот_69

Clipboard History - расширяем функционал буфера обмена

Четверг, 14 Июля 2016 г. 10:59 (ссылка)


5672195_2573c2fca352c03eedda69e58387bbc9 (449x451, 52Kb)


Clipboard History – приложение, позволяющее сохранять для последующего использования до 100 отрывков скопированного в буфер обмена текста. Программа автоматически интегрируется в системный трей для возможности быстрого доступа и имеет специальную горячую клавишу, которая позволяет вызывать список сохраненных отрывков текста.
Читать дальше.../Скачать
Метки:   Комментарии (1)КомментироватьВ цитатник или сообщество

Следующие 30  »

<google chrome - Самое интересное в блогах

Страницы: [1] 2 3 ..
.. 10

LiveInternet.Ru Ссылки: на главную|почта|знакомства|одноклассники|фото|открытки|тесты|чат
О проекте: помощь|контакты|разместить рекламу|версия для pda