2
respostas

Crash ao tentar exibir imagem em card

Estou migrando de Vue2 para Vue3 + TS, muito diferente mas estou conseguindo avançar, mas me deparei com um problema que não consigo resolver. Tenho uma lista que possui um icon que ao clicar ele exibe uma modal que mostra uma imagem que é fornecida pelo backend. Pela parte do backend tudo funciona bem, pois tenho a mesma aplicação rodando em Vue2 e funciona perfeito, tambem realizo testes usando postman e a imagem é exibida corretamente, mas quando uso o projeto em vue 3 a imagem não é renderizada e aparece crashada.

Essa é a classe do Axios que faz a requisição que é realizada corretamente, devolvendo tudo certinho

import axios, { AxiosInstance } from "axios";
import { BASE_URL } from "./url";
import { store } from "@/store";

const httpClient: AxiosInstance = axios.create({
  baseURL: BASE_URL,
  headers: {
    Accept: "*/*",
    "Content-type": "image/jpeg",
    responseType: "arrayBuffer",
  },
});

httpClient.interceptors.request.use(
  function (config) {
    const token = store.getters.getToken;
    if (token) {
      config.headers.Authorization = "Bearer " + token;
    }
    return config;
  },
  function (error) {
    return Promise.reject(error);
  }
);

export default httpClient;

Esse é a parte do html

<template>
  <div class="modal" :class="{ 'is-active': show }">
    <div class="modal-background"></div>

    <div class="modal-card">
      <header class="modal-card-head">
        <p class="modal-card-title">Display do Produto</p>
        <button class="delete" aria-label="close" @click="close()"></button>
      </header>
      <section class="modal-card-body">
        <figure>
          <img :src="figura == null ? require('/static/images/default.png') : figura" />
        </figure>
      </section>
      <footer class="modal-card-foot">
        <button class="button is-success" @click="loadPicture()">Load</button>
        <button class="button" @click="close()">Close</button>
      </footer>
    </div>
  </div>
</template>

Esse é o metodo em TS que carrega a image octet-stream base64

data() {
    return {
      figura: null as string | ArrayBuffer | null,
    };
  },
  
  methods: {
    loadPicture() {
      if (this.editing.id != 0) { //teste para verificar se o produto existe
        const filename = this.editing.id + ".jpg";
        this.store.dispatch(DOWNLOAD_FILE, filename).then((file) => {
          const blob = new Blob([file]);
          const reader = new FileReader();
          reader.readAsDataURL(blob);
          reader.onload = (e) => {
            if (e.target != null) {
              this.figura = e.target.result;
            }
          };
        });
      }
    },
}

No vue 2 eu usava boostrapvue com a tag b-img, na versão do vue 3 eu uso o Bulma com a tag img normal, acho que não deveria apresentar diferença quanto a isso, mas já tentei de tudo e não consigo fazer com que a imagem seja carregada. ![](Insira aqui a descrição dessa imagem para ajudar na acessibilidade )

2 respostas

Oi

  1. Tratamento de Resposta no Axios: Certifique-se de que a resposta do backend está sendo tratada corretamente pelo Axios. Você está configurando o responseType como "arrayBuffer", o que é apropriado para imagens. No entanto, ao processar a resposta, você pode precisar convertê-la para o formato adequado antes de atribuir à propriedade figura.

    reader.onload = (e) => {
      if (e.target != null) {
        this.figura = e.target.result.toString(); // Convertendo o arrayBuffer para string
      }
    };
    
  2. Verificar a Resposta do Backend: Antes de processar a resposta no frontend, verifique o formato da resposta que você está recebendo do backend. Certifique-se de que a imagem está sendo transmitida corretamente e que o formato está de acordo com o que você espera.

  3. Configuração do Axios: A configuração do Axios pode estar afetando a resposta. Em vez de configurar diretamente o headers na instância do Axios, você pode tentar configurá-los diretamente na requisição.

    const response = await httpClient.get(`/sua-rota-aqui/${filename}`, {
      headers: {
        Accept: "*/*",
        "Content-type": "image/jpeg",
        responseType: "arrayBuffer",
      },
    });
    
  4. Verificação de Erros: Adicione tratamento de erros para verificar se há algum erro durante a requisição ou ao processar a imagem. Isso pode ajudar a identificar se há algum problema ocorrendo durante o processo.

    this.store.dispatch(DOWNLOAD_FILE, filename)
      .then((file) => {
        // Processamento da imagem
      })
      .catch((error) => {
        console.error("Erro ao carregar a imagem:", error);
      });
    

Tente implementar essas sugestões e veja se alguma delas resolve o problema. Se o problema persistir, pode ser útil verificar mensagens de erro específicas no console do navegador para obter mais informações sobre o que pode estar causando o problema.

Item 1 - Tratamento de Resposta no Axios: Realizei as modificações para receber uma string e o resultado foi o mesmo.

Item 2 - Verificar a Resposta do Backend: Verifiquei a resposta do backend e o MIME type, está tudo correto, não acho que seja um problema com o backend porque outros aplicativos recebem a resposta normalmente e exibem a imagem corretamente, por exemplo: ![](Insira aqui a descrição dessa imagem para ajudar na acessibilidade )

Item 3 - Configuração do Axios: Acredito que o problema esta aqui, acho que o javascript está codificando o array errado, alguns caracteres diferente ou encoder, ou alguma função que substitua caracteres, mas não sei. Ao observar a imagem acima, o array que mostra a imagem e o que crasha, da pra perceber que o que não carrega está cheio de caracteres + , numeros e barras / o que parece algum erro de codificação

loadPicture() {
      if (this.editing.id != 0) {
        const filename = this.editing.id + ".jpg";
        this.store.dispatch(DOWNLOAD_FILE, filename).then((file) => {
          const blob = new Blob([file]); // na hora da criação do blob com a resposta e provoca um erro nos dados, ou altera caracteres
          const reader = new FileReader();
          reader.readAsDataURL(blob); // na hora da leitura do blob
          reader.onload = (e) => {
            if (e.target != null) {
              this.figura = e.target.result;
            }
          };
        });
      }
    },

Item 4 - Verificação de Erros: Já realizo o tratamento dos erros conforme mencionado, e o console não mostra qualquer erro.

[DOWNLOAD_FILE](contexto, id: string) {
      return httpImages
        .get(`${DW_PRODUTO_FIG + id}`)
        .then((response) => response.data)
        .catch((error) => console.log(error));
    },

Será que alguém pode ajudar ?