본문 바로가기
개발 이야기/Flutter

Flutter, Image Codec Exception 그리고 CORS Policy...

by 정선한 2023. 1. 19.
728x90
반응형

 Flutter로 개발을 하는 것은 처음이기에 니꼬쌤의 강의를 들으면서 무사히 첫 프로젝트를 완성할 수 있었습니다. 강의를 따라 하면 큰 오류는 마주칠 일이 없는데요. 그래도 각자의 환경과 선택한 플랫폼에 따라서 다양한 오류가 발생할 수밖에 없는 것이 멀티플랫폼의 영역인 것 같습니다.

그중 하나가 처음 이미지를 로드해 올 때, Image Codec Exception으로 인하여 아래의 좌측 이미지처럼 저희가 흔히 말하는 엑박(엑스박스)이 하나 떴습니다. 
니꼬 선생님의 환경은 IOS 애뮬레이터를 통해서 결과를 보고 계셨고 저는 Chrome OS 즉 웹 환경에서 결과를 보고 있었는데요. 저뿐만이 아닌 다른 웹 환경에서 테스트를 하고 계시던 많은 분들이 이 오류를 보신 것 같더라고요.

이 문제에 대한 해결방법은 (1) 오른쪽의 이미지처럼 user settings(json) 파일에서 flutterRunAdditinalArgs를 추가하여 주는 방법이 있습니다.

flutter run -d chrome --web-renderer html
flutter build web --web-renderer html

(2) 혹은 위의 코드블록처럼 flutter 명령어로 terminal에서 해당 명령들을 실행해 주어도 됩니다.


이 오류에 대한 해결 방법도 위에 먼저 기술해 보았습니다. 하지만 근본적으로 어떤 오류이고 이것이 왜 발생하는지를 아는 것이 더 중요하기에 관련한 내용을 이 아래에 첨부합니다.

Failed to load resource: net::ERR_FAILED :63577/#/:1 Access to XMLHttpRequest 
at 'https://shared-comic.pstatic.net/thumb/webtoon/800770/thumbnail/thumbnail_IMAG21_d2e1e7ee-fc83-4030-a1e7-200378bc088f.jpg' 
from origin 'http://localhost:63577' has been blocked by CORS policy
: No 'Access-Control-Allow-Origin' header is present on the requested resource.

일단 크롬의 개발자 도구의 콘솔에서 확인한 오류는 이러합니다. 그리고 해당 오류에 대한 MDN 문서도 첨부합니다.

원인은 리소스를 로드하는 것에 실패하였다는 것이고 XMLHttpRequest를 호출하여 접근하는 과정에서 어떠한 문제가 발생하였나 봅니다. 정확하게는 리소스를 요청한 header에 'Access-Control-Allow-Origin' 속성이 없어서 CORS Policy에 의하여 막혔다. 가 이 오류의 내용입니다.

저는 웹 개발자가 아니기에 이런 웹의 보안정책에 대해서 아는 바가 없습니다. 그래서 CORS Policy가 무엇인지 Access-Control-Allow-Origin 무엇인지 사실 잘 몰라서 검색을 해보았습니다. 앱에서는 사실 이런 오류를 마주할 일이 크게 없거든요. Manifest에 이미 다 Permission들을 등록해 놓고 보통 개발을 하기에 정책적으로 블락을 당하는 일이 없어서 생소한 경험이었습니다.

Origin이란 아래와 같은 형태의 것을 말하는데, 그냥 웹 주소를 Origin이라고 하는 것 같아요. 말로만 자주 들어보았지 막상 Origin을 MDN에서 검색하는 게 처음이었답니다...ㅎ

Origin: null
Origin: <scheme> "://" <hostname> [ ":" <port> ]

http://localhost:63577 이 자체를 Origin이라고 볼 수 있겠네요. 여기서 port는 생략이 가능한 형태입니다.

일단 CORS Policy는 이 Origin에 대한 기존의 웹 보안 정책인 SOP를 완화하기 위해서 만들어진 정책이라고 합니다. 자, 이러면 SOP가 무엇인지도 알아야겠죠. MDN문서는 친절하게 링크도 걸어줍니다😊

SOP는 Same Origin Policy로 같은 Origin으로 불려진 스크립트에 대하여 다른 Origin을 통한 리소스의 참조를 제한하는 것을 말합니다. 그러니까 내가 접속한 Origin의 스크립트에서는 리소스를 불러올 때도 같은 Origin을 통하여 불러와야 한다는 내용이에요.
이때 Origin이 달라지는 기준은 [프로토콜] [호스트네임] [포트번호]입니다. 이 3가지에 대한 기본 내용이 변화되는 것을 Origin이 다르다고 웹 정책은 말해주고 있어요.

MDN의 SOP문서의 하단까지 내려가면 CORS를 이용한 교차접근의 허용을 해주는 방법들도 제시하고 있습니다. 상황에 따라 맞는 방법을 허용해 주면 되겠죠.

  1. Cross-Origin Network Access
  2. Cross-Origin Script API Access
  3. Cross-Origin Data Storage Access

일단 일반적인 웹 개발이 아닌 Flutter를 통한 개발이기 때문에 관련내용을 찾아보았을 때는 다양한 해결방법들이 있고, 저는 그중에 가장 간단해 보이는 user settings 파일을 수정하는 것으로 해결을 하였습니다.

StackOverFlow에 더 많은 내용이 있어서 해당 글의 링크를 일단 첨부하였는데요. dart pub에서 해당 솔루션을 제공하고 있는 것 같으니 실무에서는 그 방법으로 해결하는 것이 가장 좋아 보이기는 합니다.

https://pub.dev/packages/flutter_cors

이미지가 로드가 안 되는 것에서 시작하여 여기까지 와버렸네요.

728x90
반응형