Extensão da Web entre navegadores para scripts personalizados Parte 4

Neste artigo, estou completando uma série de publicações nas quais queria falar sobre minha experiência em escrever uma extensão da Web para navegadores. Eu já tinha experiência na criação de uma extensão da Web, instalada por cerca de 100.000 usuários do Chrome, que funcionavam de forma autônoma, mas nesta série de artigos eu decidi me aprofundar no processo de desenvolvimento da extensão da Web, integrando-a firmemente ao lado do servidor.

imagemimagemimagemimagemimagem

Parte 1 , Parte 2 , Parte 3

Tarefas agendadas


A extensão da web permite que você configure um script personalizado para executar automaticamente seu código após o carregamento da página. Isso é conveniente, por exemplo, quando você tem uma lista de páginas do mesmo tipo para rastrear e receber dados da execução do script. Ou, se você precisar remover anúncios irritantes em qualquer página da Internet, um código para rastrear suas ações em um recurso da Web, alterar o plano de fundo da página para escuro, etc.

Nesse caso, geralmente é necessário receber dados da página no modo de programação diária. Por exemplo, se o site possui taxas de câmbio e uma solicitação direta por URL protege o argumento de hash. Como uma cópia, você pode considerar o site do Banco Central da Europa . Nesse caso, para obter as taxas de câmbio atuais, você deve conhecer o URL com hash para obter os dados corretos no formato XML.

Usando a extensão da web, você pode definir a frequência necessária para o recebimento de dados por meio de um script para solicitar taxas de câmbio. A extensão da Web aceita uma sequência no formato de coroas como uma entrada; portanto, para obter taxas de câmbio no modo diário, você deve especificar * * / 1 * * *.

Do ponto de vista técnico, a parte do servidor inicia o Puppeteer com a adição de um script de usuário à página do navegador Chromium. Nesse caso, somos confrontados com o problema do desligamento intencional do processo Chromium ao longo do tempo, pois um aumento no número de processos afetará adversamente o desempenho geral do lado do servidor. Se você planeja executar o script do usuário no modo periódico para resolver o problema acima, envie uma solicitação do script do usuário ao Puppeteer para concluir o processo do Chromium.

Após longos testes do processo de implementação do planejador de tarefas, foi decidido rastrear a saída do console de scripts. Portanto, para interromper o processo do Chromium, o script do usuário deve ter um comando para interromper o processo na seção necessária do código:

console.log('script is ended'); 

Usando este comando, um script de usuário pode fechar o processo do servidor Chromium gerado pelo Puppeteer. Isso é implementado rastreando o evento "console" do Puppeteer:

 //initialize browser and page page.on('console', async msg => { for (let i = 0; i < msg.args().length; ++i) { if(await msg.args()[i].jsonValue() == 'script is ended') { await browser.close(); } } }); 

Se o script do usuário não possuir esse comando, para concluir o processo de execução no modo do planejador de tarefas, é necessário que o cronômetro termine à força. Isso é implementado de maneira simples usando setTimeout:

 const timeLimitCron = 30; const timeout = setTimeout(async () => { if(browser) { await browser.close(); } clearTimeout(timeout); }, timeLimitCron * 1000 ); //time limit for cron, then forced closing, default 30 seconds 

Como o agendador de tarefas é executado no lado do servidor e o usuário geralmente precisa usar um endereço IP específico, uma opção para usar um servidor proxy foi adicionada.



O usuário também pode baixar o log de mensagens mais recente no console do Puppeteer. Por exemplo, é conveniente verificar a operação correta do servidor proxy.

Atalhos do teclado


Durante os testes e testes de campo, verificou-se que, para alguns tipos de scripts, é útil ter teclas de atalho para execução nos recursos da web. Um exemplo desse script é o Redability.js. Este script cria uma "visão limpa" para ler o conteúdo do site. Ou seja, a biblioteca js analisa a estrutura da página com o conteúdo e permite obter com alta probabilidade o título, o autor e o conteúdo da página. Depois disso, o script do usuário pode substituir o html do recurso da Web e permitir que o usuário leia em "forma pura", sem marcação, publicidade, etc.

Inicialmente, a execução de um script de usuário era possível apenas a partir de uma extensão da Web pop-up, clicando no botão "Executar". Essa lógica de interação com a interface geralmente é justificada por considerações de segurança. Mas no exemplo acima, ele não permite que você traga facilmente o conteúdo de um recurso da Web para uma "forma pura".

Como descrito acima, a extensão da web permite trabalhar com o DOM por meio do content.js, mas o objeto de janela não pode ser usado, por exemplo, para armazenar parâmetros, pois não é um objeto de janela de uma guia aberta. Essa condição restringe a operação da extensão da web como um objeto para rastrear pressionamentos de tecla.

No problema a ser resolvido, é necessário transferir as “teclas de atalho” da interface de extensão da web para o lado do servidor para armazenamento. Em seguida, sempre que você carregar uma página de recursos da Web, obtenha uma lista de “teclas de atalho” e carregue um script de usuário após clicar na combinação correta. Hotkeys.js é usado como uma biblioteca para trabalhar com teclas de atalho.

Após receber a lista de teclas de atalho do lado do servidor, o seguinte código é executado:

 var hotKeysMap = {keys: [], id: []}; for(var i in data.response.data) { hotKeysMap.keys.push(data.response.data[i]['hotkeys']); hotKeysMap.id.push(data.response.data[i]["_id"]); } if(hotKeysMap.keys) { getScript("hotkeys.js", function() { var script = document.createElement("script"); script.setAttribute("class", "gCore-hotKeys"); script.setAttribute("data-endpoint", event.data.endPoint); script.setAttribute("data-token", event.data.token); script.setAttribute("data-userid", event.data.userId); script.innerHTML = "GChotKeys = JSON.parse(\"" + JSON.stringify(hotKeysMap).replace(/"/g, "\\\"") + "\");\n" + "hotkeys(GChotKeys.keys.join(','), function(event, handler) {" + " event.preventDefault();" + " localStorage.setItem('runHotKeysScript', GChotKeys.id[GChotKeys.keys.indexOf(handler.key)]);" + "});"; document.body.appendChild(script); }); } 

A função getScript gera código html para a tag de script e a grava na página de recursos da web. Assim, temos em cada página a capacidade de rastrear pressionamentos de teclas. Também precisamos passar uma matriz de teclas de atalho correspondentes ao ID do script para executar. Isso é implementado adicionando código html à tag de script, cujo conteúdo inicia uma variável global para armazenar a matriz correspondente no formato JSON.

Já foi mencionado acima que há um problema de comunicação entre a página aberta do recurso da Web e o script extension.js da extensão da extensão da web, usado para manipular o DOM. Nesse caso, você pode recorrer a uma técnica simples para verificar o valor em localStorage, que é um objeto comum para os dois pontos de interação mencionados acima.

No content.js, você pode simplesmente verificar o valor localStorage uma vez por segundo e executar as mesmas manipulações DOM como quando clicou no botão "Executar" na extensão da Web pop-up.

 setInterval(function() { if(localStorage.getItem('runHotKeysScript')) { // run user script localStorage.removeItem('runHotKeysScript'); } }, 1000); 

Assim, a técnica de "teclas de atalho" é implementada, o que permite iniciar rapidamente scripts de usuário usando o poder da biblioteca interna para resolver problemas práticos.

Conclusão


Durante a implementação deste projeto, foram resolvidas as tarefas práticas de escrever a integração entre a parte do servidor com base no meteor.js e a extensão da web para vários navegadores. Os principais obstáculos foram o SCP e os processos de interação entre os três componentes da parte do cliente - a página aberta no navegador, os scripts content.js e background.js.

Espero que minha experiência facilite a criação de extensões da web para navegadores mais especializados.

No futuro, está planejado localizar a extensão da Web e escrever scripts úteis para a comunidade. Se o leitor tiver uma idéia ou desejo de ajudar a escrever esses scripts de usuário, escreva em mensagens privadas.

Source: https://habr.com/ru/post/pt417391/


All Articles