O erro "xhr.upload.addEventListener is not a function" é um problema comum ao lidar com o envio de arquivos e o monitoramento de progresso em requisições assíncronas. Essa exceção geralmente é lançada quando a propriedade upload não está disponível ou não é um objeto válido no contexto da instância atual.
Causas Comuns e Soluções Básicas
Antes de investigar bibliotecas de terceiros, verifique os seguintes pontos no seu código:
- Vinculação Incorreta: Certifique-se de que o ouvinte de eventos está sendo anexado especificamente à propriedade
uploadda instância, e não ao objeto raiz da requisição. - Compatibilidade e APIs Obsoletas: Navegadores muito antigos podem não suportar a API de upload. Consulte a documentação atualizada no MDN Web Docs para garantir a compatibilidade.
- Erros de Sintaxe: Utilize linters como ESLint para identificar possíveis falhas estruturais no seu script.
Exemplo de implementação correta para monitoramento de progresso:
const clienteHttp = new XMLHttpRequest();
// Vinculando o evento corretamente à propriedade upload
clienteHttp.upload.addEventListener('progress', (evento) => {
if (evento.lengthComputable) {
const percentual = (evento.loaded / evento.total) * 100;
console.log(`Progresso: ${percentual}%`);
}
});
clienteHttp.open('POST', '/api/envio');
clienteHttp.send(dadosDoFormulario);
Conflitos com a Biblioteca MockJS
Se o seu código estiver correto e o erro persistir, o problema pode estar relacionado ao uso do MockJS. Essa biblioteca é amplamente utilizdaa para simular respostas de API e gerar dados fictícios. No entanto, ela intercepta e sobrescreve o objeto XMLHttpRequest nativo do navegador. Durante esse processo, a propriedade upload é frequentemente substituída por um objeto vazio ou indefinida, o que quebra a cadeia de métodos e impede o envio de arquivos.
Para contornar essa limitação sem remover o MockJS do seu projeto, você pode restaurar temporariamente a referência nativa do XMLHttpRequest antes de executar a requisição de upload:
// Armazena a implementação original do navegador
const XHRNativo = window.XMLHttpRequest;
// Substitui a instância mockada pela nativa
window.XMLHttpRequest = XHRNativo;
// Executa a requisição real de upload
const requisicaoReal = new XMLHttpRequest();
requisicaoReal.open('POST', '/endpoint/de/upload');
requisicaoReal.send(payloadDoArquivo);
// Reativa o MockJS para as demais requisições da aplicação
window.XMLHttpRequest = MockXMLHttpRequest;
Caso a manipulação direta do objeto window não seja viável no seu ambiente, considere migrar para ferramentas de teste e simulação mais robustas, como o Sinon.js. O Sinon permite criar stubs e mocks precisos para o XMLHttpRequest e sua propriedade upload, evitando a destruição de APIs nativas essenciais.