ноль, введение
В этой статье представлен процесс реализации плагина для браузера Chrome, который в основном включает в себя:
- Что такое плагин для браузера
- каталог плагинов
- Связь с плагином
- Отладка плагина
- Реализация проекта
- Выпуск плагина
- Справочная документация
1. Что такое плагин для браузера?
Плагины браузера — это инструменты, добавляющие новые функции на основе исходных функций браузера. Это не независимое программное обеспечение, и для работы его необходимо подключить к соответствующему браузеру. В настоящее время основные браузеры позволяют использовать плагины для улучшения функций браузера и сделать его более разнообразным. Разработка плагина для браузера на самом деле аналогична разработке веб-приложения, состоящего из HTML+JS+CSS.В этой статье будет представлена реализация плагина функции захвата изображения. Этот плагин в основном используется для сбора изображений веб-страниц и их хранения на сервере.
2. Каталог плагинов
Каталог подключаемого модуля браузера Chrome, реализованного в этой статье, показан на следующем рисунке:
2.1 файл manifest.json
В корневом каталоге находится файл manifest.json, в котором содержится список функций и файлов конфигурации всего плагина.Это очень важный и необходимый файл для приложения плагина, и его необходимо поместить в корневой каталог. Среди них манифест_версия, имя и версия являются обязательными, а описание и значки являются рекомендуемыми параметрами.
{
"manifest_version": 2, // 清单文件的版本,这个必须写,而且必须是2
"name": "图片采集", // 插件的名称
"version": "1.0.0", // 插件的版本
"description": "这是一个图片采集插件", // 插件描述
"icons": { // 插件图标
"16": "static/img/icon.png"
"48": "static/img/icon.png"
"128": "static/img/icon.png"
},
}
2.2 Шаблон страницы
Каталог шаблонов используется для размещения шаблонов страниц, обычно используются popup.html и background.html.
popup.html — это веб-страница окна, которая появляется при нажатии на значок плагина и закрывается сразу после того, как фокус покидает веб-страницу окна, которая используется для взаимодействия с пользователем. В подключаемом модуле коллекции изображений пользователям доступны две кнопки: «Предварительный просмотр всех изображений» и «Показать кнопку захвата».
{
"browser_action": {
"default_icon": "static/img/icon.png",
"default_title": "",
"default_popup": "template/popup.html"
},
}
background.html является фоновой страницей и резидентной страницей, ее жизненный цикл самый продолжительный среди всех типов страниц в плагине, она открывается при открытии браузера и закрывается при закрытии браузера, поэтому обычно необходимо Всегда работающий, запускаемый и глобальный код помещается в файл background.html, который можно понимать как фоновый сценарий, который подключаемый модуль запускает в браузере. Например, иногда плагину необходимо взаимодействовать с сервером для выполнения синхронизации данных и других операций, эта операция не воспринимается пользователем, поэтому его можно разместить на фоновой странице для запуска этой части логики.
Укажите фоновую страницу через поле background манифеста:
{
// 2种指定方式,如果指定JS,那么会自动生成一个背景页
"page": "template/background.html"
// "scripts": ["static/js/background.js"]
}
2.3 Статические файлы
В каталоге static размещаются статические файлы, включая изображения, сценарии js и стили css.
icon.png — это значок плагина.
content-script.js — это сценарий js, внедренный подключаемым модулем на веб-страницу. Используя стандартную модель DOM, он может считывать сведения о веб-странице или изменять ее структуру DOM. Связь между веб-страницей и плагин также может быть достигнут через него. В подключаемом модуле коллекции изображений он в основном используется для работы с веб-страницами для получения изображений.
popup.js — это js-скрипт popup.html. В подключаемом модуле захвата изображений главный пользователь собирает сведения о взаимодействии с пользователем и сообщает content-script.js, чтобы он управлял веб-страницей для захвата изображений.
background.js — это js-скрипт background.html. В подключаемом модуле коллекции изображений он в основном используется для хранения собранных изображений на сервере.
content-script.css — это стиль CSS, который подключаемый модуль внедряет на веб-страницу.
content-script можно внедрить через конфигурацию манифеста:
{
"content_scripts": [{
"matches": ["<all_urls>"], // <all_urls> 表示匹配所有地址
"js": ["static/js/jquery-1.8.3.js", "static/js/content-script.js"], // 多个js顺序注入
"css": ["static/css/content-script.css"], //css注入
"run_at": "document_end" // 代码注入的时间,可选值: document_start, document_end, or document_idle,最后一个表示页面空闲时,默认document_idle
}]
}
3. Подключаемый модуль связи
3.1 Связь контекста плагина
И popup.js, и background.js запускаются в контексте плагина.Поскольку они запускаются в одном потоке, связь между ними относительно проста, и страницы могут напрямую вызывать методы друг друга для передачи информации. Например, метод chrome.extension.getViews() может возвращать список оконных объектов, принадлежащих каждой активной странице вашего плагина, а метод chrome.extension.getBackgroundPage() может возвращать фоновую страницу.
// background.js
var views = chrome.extension.getViews({type:'popup'}); // 返回popup对象
if(views.length > 0) {
console.log(views[0].location.href);
}
function test(){
console.log('我是background');
}
// popup.js
var bg = chrome.extension.getBackgroundPage();
bg.test(); // 访问background的函数
console.log(bg.document.body.innerHTML); // 访问background的DOM
3.2 контент-скрипт взаимодействует с контекстом плагина
content-script.js — это скрипт, встроенный в веб-страницу, поэтому он фактически работает в контексте веб-страницы и полностью изолирован от контекста плагина.Нет возможности вызывать методы для взаимодействия друг с другом, как страницы связаны с контекстом плагина. Для облегчения связи требуется канал связи. В подключаемом модуле сбора изображений content-script.js получает сообщения от popup.js для сбора изображений веб-страниц и отправляет сообщения в background.js для хранения изображений.
popup.js или background.js активно отправляет сообщение в content-script.js:
function sendMsgToContentScript(message, callback){
chrome.tabs.query({active: true, currentWindow: true}, function(tabs){
chrome.tabs.sendMessage(tabs[0].id, message, function(response){
if(callback) callback(response);
})
})
}
sendMsgToContentScript({type: 'popMsg', value: '你好, 我是popup'}, function(response){
console.log('来自content的回复:' + response);
})
content-script.js получает сообщение:
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse){
if(request.type === 'popMsg'){ console.log('收到来自popup的消息:' + request.value);
}
sendResponse('我是content-script,已收到你的消息');
})
content-script.js заранее отправляет сообщение в popup.js или background.js:
chrome.runtime.sendMessage({type: 'contentMsg', value: '你好,我是content-script'},function(response){
console.log('收到来自后台的回复:'+ response);
})
popup.js и background.js получают сообщение:
chrome.runtime.onMessage.addListener(function(request, sender, sendResonse){
console.log()
if(request.type === 'contentMsg'){
console.log('收到来自content-script的消息:' + request.value);
}
sendResonse('我是后台,已收到你的消息。');
})
Следует отметить, что предпосылкой активной отправки сообщений в popup.js из content-script.js является то, что страница всплывающего окна должна быть открыта, в противном случае background.js необходимо использовать в качестве реле.
В-четвертых, отладка плагинов
4.1 Установите комплект разработки плагинов
1. Откройте страницу управления плагинами. Войдите на страницу управления плагинами через меню браузера или напрямую введите chrome://extensions в адресной строке для доступа.
2. Проверьте режим разработчика. После проверки можно напрямую загрузить папку приложения плагина, иначе может быть установлен только сжатый файл в формате .crx, а обновление плагина не синхронизируется по времени.
3. Обновление плагина. Любые изменения в коде в процессе разработки требуют перезагрузки плагина, просто нажмите кнопку обновления плагина, на всякий случай лучше также обновить страницу.
4.2 Отладка содержимого-script.js
content-script.js — это скрипт, который запускается на веб-странице, и вы можете отладить его, открыв инструменты разработчика веб-страницы.
4.3 Отладка background.js
Поскольку background.js и content-script.js не работают в одном контексте, окно отладки веб-страницы не может видеть background.js. Для отладки background.js необходимо открыть окно отладки плагина. На странице управления подключаемым модулем щелкните "Просмотреть шаблон представления/background.html" вашего подключаемого модуля, и появится окно отладки подключаемого модуля. Следующая операция аналогична обычной отладке веб-страницы.
4.4 Отладка popup.js
Хотя popup.js и background.js находятся в одном контексте, если вы хотите увидеть popup.js, вам нужен еще один шаг, чтобы «щелкнуть, чтобы просмотреть содержимое всплывающего окна»:
5. Реализация проекта
5.1 Реализация веб-страницы с всплывающим окном
Веб-страница всплывающего окна предоставляет пользовательский интерфейс, который в основном включает следующие функции:
- Когда пользователь нажимает кнопку «Предварительный просмотр всех загруженных изображений», popup.js уведомляет content-script.js о необходимости прочитать DOM веб-страницы, отфильтровать DOM изображения и удалить ссылку на изображение. Затем используйте DOM, чтобы создать диалоговое окно на веб-странице, и поместите все изображения в диалоговое окно для централизованных операций предварительного просмотра и сбора.
- Пользователь переключает флажок «Отображает ли страница кнопку захвата изображения». Если этот флажок установлен, popup.js уведомит сценарий контента о необходимости управлять DOM веб-страницы и добавит кнопку захвата к изображению. Если этот флажок не установлен, popup.js уведомит скрипт содержимого об удалении кнопки захвата на веб-странице.
<!-- popup.html -->
<div>
<div id="preViewAllImg">
<img src="https://s10.mogucdn.com/mlcdn/c45406/190219_4949lfk7le758fei1825i6dkd4g9i_40x42.png" />预览全部已加载图片
</div>
<div class="collect_btn_wrap" id="showCollectBtn">
<div class="collect_btn">
<div class="show_collect_check"><img class="collect_check_img" src="" /></div>页面显示收藏按钮
</div>
</div>
</div>
<script type="text/javascript" src="../static/js/jquery-1.8.3.js"></script>
<script type="text/javascript" src="../static/js/popup.js"></script>
<!-- popup.js -->
$(function () {
function sendMsgToContentScript(message, callback){
chrome.tabs.query({active: true, currentWindow: true}, function(tabs){
chrome.tabs.sendMessage(tabs[0].id, message, function(response){
if(callback) callback(response);
})
})
}
// 一键收集全部图片
$('#preViewAllImg').click(e => {
sendMsgToContentScript({type: 'REQUEST_PREVIEW_ALL_IMG', title: '我是popup, 请采集所有已加载图片并进行预览'}, function(response){
console.log('我是popup, 来自content的回复:' + response);
});
});
// 是否显示采集按钮
$('#showCollectBtn').click(() => {
var src = $('.collect_check_img').attr('src');
var status = src === ''; // status: true 显示
$('.collect_check_img')[0].src = src === '' ? 'https://s10.mogucdn.com/mlcdn/c45406/190219_0728g95i8bkl3i08jic6lhjhh7gae_24x18.png' : '';
// 向content-script发送消息显示or隐藏单个商品的收藏按钮
sendMsgToContentScript({type: 'REQUEST_SWITCH_COLLECT_BTN', title: `我是popup, 请${status?'显示':'隐藏'}采集按钮`, status}, function(response){
console.log('我是popup, 来自content的回复:' + response);
});
});
})
5.2 Реализация сценария вставки содержимого-скрипта
content-script будет прослушивать сообщения от popup.js, управлять DOM веб-страницы в соответствии с уведомлением о сообщении, выполнять такие операции, как чтение ссылок на изображения, добавление кнопок захвата изображений, захват изображений и т. д., а также отправка сообщения на фон, чтобы уведомить его о сохранении захваченных ссылок на изображения.
<!-- content-script.js -->
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
if(request.type === 'REQUEST_PREVIEW_ALL_IMG'){
console.log('我是content-script,收到来自popup的消息:' + request.title);
sendResponse('我是content-script, 已收到你的预览全部图片的消息');
PreviewAllImg();
}else if(request.type === 'REQUEST_SWITCH_COLLECT_BTN'){
console.log('我是content-script,收到来自popup的消息:' + request.title);
sendResponse(`我是content-script, 已收到你${request.status ? '显示':'隐藏'}采集按钮的消息`);
if(request.status){
ShowCollectBtn();
}else{
ClearCollectBtn();
}
}else if(request.type === 'COLLECT_RESULT'){
console.log('我是content-script,收到来自background的消息:' + request.title);
sendResponse(`我是content-script, 已收到你的${request.title}的消息`);
}
});
// 预览所有已加载图片
function PreviewAllImg(){
GetAllAttrList('img', ['src', 'data-src']).then((res) => {
ShowImgPanel(res);
})
}
// 展示采集按钮
function ShowCollectBtn(){
$('img').each((index, item) => {
let src = $(item).attr('src') || $(item).attr('data-src');
$($(item).parent()).css('position', 'relative');
$($(item).parent()).find('.collect_img_btn').remove();
$($(item).parent()).append('<div class="collect_img_btn" data-src="'+src+'">采集</div>');
});
$('.collect_img_btn').click((e) => {
e.stopPropagation();
e.preventDefault();
let src = $(e.target).data('src');
chrome.runtime.sendMessage({type: 'SEND_IMG', src: src},function(response){
console.log('我是content-script, 收到来自后台的回复:' + response);
})
});
}
// 清除采集按钮
function ClearCollectBtn(){
$('.collect_img_btn').remove();
}
// 展示预览图片对话框
function ShowImgPanel(list){
var panelDOM = $('<div id="collect_img_panel">' +
'<div class="collect_img_panel_close">x</div>' +
'<div class="collect_img_panel_content">x</div>' +
'</div>');
$('body').append(panelDOM);
$('body').append('<div id="collect_img_panel_mask"></div>');
let $item = '';
$.each(list, function(index, item) {
$item = $item + '<div class="collect_img_panel_item">' +
'<div class="collect_img_panel_item_img" style="background-image: url(' + item + ')"></div>' +
'<div class="collect_img_panel_item_mask"></div>' +
'<div class="collect_img_panel_item_btn" data-src="'+ item+'">采集图片</div>' +
'</div>';
});
$('.collect_img_panel_content').html($item);
$('.collect_img_panel_item_btn').click((e)=>{
let src = $(e.target).data('src');
chrome.runtime.sendMessage({type: 'SEND_IMG', src: src},function(response){
console.log('我是content-script, 收到来自后台的回复:' + response);
})
});
$(".collect_img_panel_close").click(function() {
$('#collect_img_panel').remove();
$('#collect_img_panel_mask').remove();
});
}
// 根据标签和属性采集所有符合条件的对象
function GetAllAttrList(obj, attrArr){
return new Promise((resolve) => {
let list = [];
$(obj).each((index, item) => {
GetAttrContent(item, attrArr).then(res => {
list.push(res);
if(index === $(obj).length - 1){
resolve(list);
}
});
});
});
}
// 获取对象的属性内容
function GetAttrContent(obj, attrArr){
return new Promise((resolve) => {
$.each(attrArr, (attrIndex, attrItem) => {
let attrContent = $(obj).attr(attrItem);
if(attrContent){
resolve(attrContent);
}
})
});
}
5.3 Фоновая реализация фоновой страницы
Фоновая фоновая страница прослушивает сообщения от скрипта содержимого и сохраняет собранные изображения на сервере.
<!-- background.html -->
<div>
<script type="text/javascript" src="../static/js/jquery-1.8.3.js"></script>
<script type="text/javascript" src="../static/js/background.js"></script>
</div>
<!--background.js-->
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
if(request.type === 'SEND_IMG'){
alert('我是background,采集到图片链接:' + request.src);
sendResponse('正在采集图片');
requestStoreImg(request.src);
}
});
// 存储图片
function requestStoreImg(src) {
$.ajax({
type: 'get',
url: 'https:/www.mogu.com/*/store',
data: {
url: src
},
success: function(res) {
if (res.status && res.status.code && res.status.code === 1001) {
sendMsgToContentScript({type: 'COLLECT_RESULT', title: '图片采集成功'}, function(response){
alert('我是background,来自content的回复:' + response);
});
} else {
sendMsgToContentScript({type: 'COLLECT_RESULT', title: '图片采集失败'}, function(response){
alert('我是background,来自content的回复:' + response);
});
}
},
error: function(res){
sendMsgToContentScript({type: 'COLLECT_RESULT', title: '接口异常采集失败'}, function(response){
alert('我是background,来自content的回复:' + response);
});
}
})
}
function sendMsgToContentScript(message, callback){
chrome.tabs.query({active: true, currentWindow: true}, function(tabs){
chrome.tabs.sendMessage(tabs[0].id, message, function(response){
if(callback) callback(response);
})
})
}
6. Выпуск плагина
После завершения разработки пакет .crx упаковывается и генерируется через «Расширение пакета» на странице плагина.
Войдите с помощью учетной записи GoogleПанель разработчика, Заполните всю необходимую информацию, и вы можете опубликовать ее.
7. Справочные документы
developer.chrome.com/extensions open.chrome.360.capable/extension_…