Erros de script são ocorrências frequentes. No entanto, a ausência de mensagens de erro completas ou pilhas de execução dificulta a solução de problemas desse tipo. Este tópico analisa as causas, apresenta soluções e demonstra como ignorar esses erros no Application Real-Time Monitoring Service (ARMS).
Causas dos erros de script
Erros de script também são conhecidos como erros de cross-origin. Eles podem ocorrer quando um site solicita e executa um script hospedado em um domínio de terceiros. O cenário mais comum envolve o uso de uma CDN para hospedar recursos JavaScript (JS).
Para facilitar o entendimento, considere que a seguinte página HTML esteja implantada no domínio http://test.com:
<!doctype html>
<html>
<head>
<title>Test page in http://test.com</title>
</head>
<body>
<script src="http://another-domain.com/app.js"></script>
<script>
window.onerror = function (message, url, line, column, error) {
console.log(message, url, line, column, error);
}
foo(); // Invokes the foo method defined in the app.js file.
</script>
</body>
</html>
Suponha que o método foo invoque um método bar indefinido:
// another-domain.com/app.js
function foo() {
bar(); // ReferenceError: bar is not a function
}
Após o carregamento da página, o sistema captura o seguinte erro:
"Script error.", "", 0, 0, undefined
Na verdade, isso não é um erro de JS. Por motivos de segurança, os navegadores ocultam intencionalmente erros específicos lançados por arquivos JS de outras origens. Essa medida evita que informações sensíveis sejam capturadas inadvertidamente por scripts de terceiros não controlados. Portanto, apenas scripts da mesma origem conseguem capturar mensagens de erro específicas. Scripts de outras origens detectam a ocorrência do erro, mas não acessam os detalhes da mensagem. Para mais informações, consulte .
bool ScriptExecutionContext::sanitizeScriptError(String& errorMessage, int& lineNumber, String& sourceURL)
{
KURL targetURL = completeURL(sourceURL);
if (securityOrigin()->canRequest(targetURL))
return false;
errorMessage = "Script error.";
sourceURL = String();
lineNumber = 0;
return true;
}
As seções a seguir descrevem como resolver erros de script.
Solução 1: Ative o compartilhamento de recursos de cross-origin
Para capturar erros de JS entre origens, execute as etapas a seguir:
-
Adicione o atributo
crossorigin="anonymous".<script src="http://another-domain.com/app.js" crossorigin="anonymous"></script>Esta etapa instrui o navegador a obter scripts de terceiros de forma anônima. Assim, o navegador não envia possíveis informações de identidade do usuário, como cookies e certificados HTTP, ao servidor durante a solicitação dos scripts.
-
Inclua o cabeçalho de resposta HTTP de cross-origin. Por exemplo, execute o seguinte comando:
Access-Control-Allow-Origin: *Como alternativa, execute este comando:
Access-Control-Allow-Origin: http://test.comNotaPor padrão, a maioria das CDNs principais já possui o atributo
Access-Control-Allow-Origin. O exemplo abaixo vem do Alibaba Cloud CDN:$ curl --head https://retcode.alicdn.com/retcode/bl.js | grep -i "access-control-allow-origin" => access-control-allow-origin: *
Após concluir as duas etapas anteriores, capture erros de cross-origin usando o manipulador window.onerror. No exemplo acima, ao recarregar a página, o sistema captura o seguinte erro:
=> "ReferenceError: bar is not defined", "http://another-domain.com/app.js", 2, 1, [Object Error]
Solução 2: Adicionar o comando try catch (Opcional)
Se for difícil adicionar um atributo de cross-origin ao cabeçalho de solicitação ou resposta HTTP, utilize o comando try catch.
Insira o comando try catch na página HTML mencionada anteriormente. O código a seguir serve de exemplo:
<!doctype html>
<html>
<head>
<title>Test page in http://test.com</title>
</head>
<body>
<script src="http://another-domain.com/app.js"></script>
<script>
window.onerror = function (message, url, line, column, error) {
console.log(message, url, line, column, error);
}
try {
foo(); // Invokes the foo method defined in the app.js file.
} catch (e) {
console.log(e);
throw e;
}
</script>
</body>
</html>
Carregue a página novamente. O sistema retorna as seguintes informações:
=> ReferenceError: bar is not defined
at foo (http://another-domain.com/app.js:2:3)
at http://test.com/:15:3
=> "Script error.", "", 0, 0, undefined
O comando try catch gera informações completas de erro no log do console, mas o manipulador window.onerror produz apenas erros de script genéricos. Você pode relatar manualmente as exceções capturadas no bloco try catch. Para mais detalhes, consulte SDK methods.
__bl.error(error, pos);
Embora o comando try catch permita capturar algumas exceções, recomendamos o uso da Solução 1.
Como ignorar erros de script no ARMS?
Geralmente, erros de script originam-se de scripts em domínios de terceiros. Caso esses erros não afetem a execução da sua aplicação, ignore-os definindo o parâmetro ignore do SDK de monitoramento de frontend do ARMS.
O parâmetro ignore permite suprimir o relatório de erros de JS específicos. Seu valor é um objeto composto por três propriedades: ignoreUrls, ignoreApis e ignoreErrors. O código abaixo exibe o valor padrão desse parâmetro:
ignore: {
ignoreUrls: [],
ignoreApis: [],
ignoreErrors: []
},
Use a propriedade ignoreErrors para filtrar erros de script. Essa propriedade ignora erros de JS que correspondam a uma regra especificada. O valor aceito pode ser uma string (tipo String), uma expressão regular (tipo RegExp), um método (tipo Function) ou um array contendo esses três tipos. Veja a seguir um exemplo de como ignorar erros de script:
__bl.setConfig({
ignore: {
ignoreErrors: /^Script error\.?$/
}
});