๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐Ÿ’ป ๊ฐœ๋ฐœ์ž ์ด์•ผ๊ธฐ/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
๋ฐ˜์‘ํ˜•