공개/기록하기

[AWS S3] html2canvas 사용 중 s3 url 일 때 생성 안되는 오류 해결

잔망짱구 2023. 5. 16. 16:12
728x90
반응형

최근 캡스톤과 개인프로젝트, 자격증 시험 등 여러 핑계로 블로그 업로드를 미뤘는데

프로젝트 진행 중 이슈를 해결하며, 이 내용을 기록해 두면 다른 사람들에게도 도움이 되지않을까 싶어서 기록해본다!

나에겐 너무 어려운 개발 .. 이미지 출처: https://corine2.tistory.com/158

 

html2canvas 사용 중 s3 url 일 때 생성 안되는 오류

  • 계속 s3 url이 src인 이미지만 썸네일에 포함 안되는 오류가 있었다

html2canvas(imageArea, { useCORS: true }).then(canvas => { 추가하고

img.crossOrigin = 'anonymous'; 추가!

 canvas() {
      try {
        const imageArea = this.$refs.dragImage;
        html2canvas(imageArea, { useCORS: true }).then(canvas => {
          const ctx = canvas.getContext('2d');
          const img = new Image();
          img.crossOrigin = 'anonymous'; // CORS 허용
          img.onload = () => {
            // 이미지의 원본 크기 가져오기
            const originalWidth = img.width;
            const originalHeight = img.height;

            // 이미지 크기 축소 비율
            const reductionRatio = 0.35; // 30%로 축소

            // 축소된 이미지 크기 계산
            const reducedWidth = originalWidth * reductionRatio;
            const reducedHeight = originalHeight * reductionRatio;

            // 축소된 이미지 그리기
            canvas.width = reducedWidth;
            canvas.height = reducedHeight;
            ctx.drawImage(img, 0, 0, reducedWidth, reducedHeight);

            // 데이터 URL 생성
            const dataUrl = canvas.toDataURL('image/jpeg', 0.35); // JPEG 포맷, 압축률 70%
            this.currentPageList.thumbnail = dataUrl;
          }

          img.src = canvas.toDataURL();
        });
      }
      catch (err) {
        console.log(err);
      }
    },

 

html2canvas S3 url CORS 뜰 때

  • 분명히 S3 bucket에도 버킷 정책, CORS 정책이 추가되어있는데 자꾸 CORS 오류 뜨는 상황이였다.

버킷 정책

http://awspolicygen.s3.amazonaws.com/policygen.html

 

AWS Policy Generator

Click below to edit. To save the policy, copy the text below to a text editor. Changes made below will not be reflected in the policy generator tool.

awspolicygen.s3.amazonaws.com

  • 위와 같이 입력 후, Actions엔 getObject, putObject 두 가지를 선택한다.
  • ARN은 arn:aws:s3:::${BucketName}/${KeyName} 입력
  • Add 후 코드 복사하기!
  • 버킷 > 원하는 버킷 이름 클릭 > 권한 > 버킷 정책 편집 > 붙여넣기

 

CORS 정책

[
    {
        "AllowedHeaders": [
            "*"
        ],
        "AllowedMethods": [
            "HEAD",
            "GET",
            "PUT",
            "POST"
        ],
        "AllowedOrigins": [
            "*"
        ],
        "ExposeHeaders": []
    }
]

같은 이슈를 겪고 있는 블로그를 찾았다. ㅠ

https://velog.io/@kimsehwan96/S3-CORS-%ED%97%A4%EB%8D%94-%EA%B4%80%EB%A0%A8-%EC%9D%B4%EC%8A%88-%ED%95%B4%EA%B2%B0%EB%B0%A9%EB%B2%95-html2canvas-lottie

CORS 정책을 정의했다고 해서 html2canvas나 혹은 lottie와 같은 것들을 바로 사용 가능한 상태는 아니다.

S3버킷은 access-control-allow-origin 헤더를 특정 상황에서만 반환하는데..

클라이언트의 리소스 요청(request)에 Origin 헤더가 있어야만 access-control-allow-origin 헤더를 내려보내준다!

위 블로그는 Cloud Front 로 이슈를 해결하였다.

댓글을 보니 트릭을 주는 방법도 있는 것 같아서 더 찾아보았다!

 

1. html2canvas.js 코드 수정

동일한 객체가 아닌걸로 하게끔 트릭 주는 법 - 블로그 참고

node_modules 폴더 안에 html2canvas -> 5766번째줄 변경

img.src = /^data:image/.test(src) ? src : src + '?' + new Date().getTime();
  • 이렇게 수정하고 나니 해결은 되었지만 node_modules 는 gitignore 라 올라가지 않아서 새로 받을 때 마다 수정해줘야했다.
  • 그래서 CloudFront 를 이용해 해결했다.

 

2. CloudFront 를 이용한 이슈 해결

CloudFront > 배포 > 만들어둔 것 클릭 > 동작 > 동작 편집

캐시 정책

정책 생성 > 이름 입력 > 캐시 키 설정

 

참고블로그1

참고블로그2

 

추가) 이미지 src가 S3 url 일 경우 생기는 CORS

crossorigin="anonymous"

<img src="<URL>" crossorigin="anonymous">

위 처럼 crossorigin 즉 동일출처정책에 대해서 익명으로 접근하겠다고 명시하면 해결된다.

아래와 같이 코드 수정 후 CORS 이슈 해결!

<div class="uploaded-image-list" v-show="selectedMenu == 'character'">
   <img :src="item.src" crossOrigin="anonymous" :id="item.id" v-for="item, index in charList">
</div>
<div class="uploaded-image-list" v-show="selectedMenu == 'background'">
    <img :src="item.src" crossOrigin="anonymous" :id="item.id" v-for="item, index in backList">
</div>

 

crossorigin?

 

<img>: The Image Embed element - HTML: HyperText Markup Language | MDN

The <img> HTML element embeds an image into the document.

developer.mozilla.org

crossorigin은 이미지를 가져오는 데 CORS(Cross-Origin Resource Sharing) 요청을 사용해야 하는지 여부를 나타내는 속성입니다. CORS 요청을 통해 반환된 CORS 활성화된 이미지의 이미지 데이터는 "tainted"로 표시되지 않고crossorigin 속성이 지정되지 않으면, CORS 요청 없이 (Origin 요청 헤더 없이) 비-CORS 요청이 전송되며, 브라우저는 이미지를 "tainted"로 표시하고 이미지 데이터에 대한 액세스를 제한하여 crossorigin 속성이 지정되면, CORS 요청이 전송되고 (Origin 요청 헤더와 함께), 그러나 서버가 원본 사이트의 이미지 데이터에 대한 교차 출처 액세스를 허용하지 않도록 설정하지 않는 한(접근 제어 허용-Origin 응답 헤더를 보내지 않거나, 보낸 응답 헤더에 사이트의 원본을 포함시키지 않음), 브라우저는 이미지 로딩을 차단하고 CORS 오류를 개발자 도구 콘솔에 기록합니다.

anonymous: 자격증명이 생략된 상태로 CORS 요청이 전송됩니다. (쿠키, X.509 인증서, Authorization 요청 헤더 없음)

 

 

728x90
반응형