[js] img onerror로 에러 처리하기(확장자 동적 변경)

jellyjw·2024년 5월 13일
0

개요

이미지 src 가 잘못되어 요청에 실패할 경우, img의 onerror 속성을 이용해 에러가 발생한 이미지에만 png 로 고정되어 있는 확장자를 jpg 로 변경해 에러 없이 모든 이미지를 띄울수 있도록 처리했다.

img onerror가 호출되는 시점

이미지 가져올 수 없는 경우 예시

  • src 속성이 비었거나 null 일 경우
  • src의 URL이 현재 사용자가 보는 페이지의 URL과 같을 경우
  • 지정한 이미지가 손상돼 불러올 수 없을 경우
  • 이미지의 메타데이터가 손상돼 원본 크기를 알아낼 수 없고, <img> 요소의 속성에도 크기를 지정하지 않았을 경우
  • 사용자 에이전트가 지원하지 않는 이미지 형식

출처 : MDN - <img>

만약 img 태그에 onerror 로 에러 처리를 등록했다면,
이미지를 가져올 수 없는 경우 error 이벤트와 함께 onerror 처리기가 호출된다.

<img src="image.jpg"
     onerror="this.src='placeholder.jpg'"
     alt="Image"
     width="200"
     height="200">

이렇게 대체 이미지도 넣어줄 수 있다.


동적으로 확장자 변경 (Vue.js)

먼저 변수와 메서드를 정의해 주었다.

  • failedImages : Set() 객체를 통해 고유하게 index를 관리할 수 있도록 했다.
  • onImgError : onerror 처리 함수
  • getImageSrc : 서버로부터 img src를 받아오는 함수
data() {
    failedImages: new Set(), 
},

methods: {
    getImageSrc(question, idx) {
      let baseUrl = `{url}`;

      return this.failedImages.has(idx)
        ? (baseUrl += `.png`)
        : (baseUrl += `.jpg`);
    },  
      
    onImgError(index) {
      this.failedImages.add(index);
      this.$forceUpdate();
    },
}

그리고, 렌더링 부분에서 (예시에서는 vuetify의 v-img를 사용했다)
@error 로 에러 처리함수를 등록해주고,

인자로 index 를 넘겨 반복문 내에서 에러가 발생한 이미지의 index만 failedImages에 담을수 있도록 처리했다.

  <template v-for="(question, idx) in questions">
     <v-img
      :src="getImageSrc(question, idx)"
      @error="onImgError(idx)"
      ... 생략
     />
  </template>

이렇게 처리하면, 위에 정의한 getImageSrc 내부에서

// 생략
return this.failedImages.has(idx) // idx가 failedImages에 존재할 경우
   ? (baseUrl += `.png`)
   : (baseUrl += `.jpg`);

에러가 발생한 이미지의 확장자만 png 에서 jpg 로 바꿔서 렌더링이 가능해진다.

이렇게 onerror 속성을 이용해서 에러나는 이미지 없이 모든 이미지를 띄울 수 있었다. 확장자를 동적으로 변경하는 경우를 제외하고도, default 이미지를 설정할 수 있어 자주 쓰일 것 같다.

끝!

profile
남는건 기록뿐👩🏻‍💻

0개의 댓글