๐Ÿ’พย ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ File ๊ฐ์ฒด๐Ÿ’พย ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ File ๊ฐ์ฒด

๐Ÿ’พย ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ File ๊ฐ์ฒด

์ตœ์ข… ํŽธ์ง‘ ์ผ์‹œ
Last updated June 14, 2022
ํƒœ๊ทธ
Javascript
๋ฐฐํฌ์ผ์ž
Apr 30, 2020
์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ ์ด๋ฏธ์ง€๋‚˜ ๋™์˜์ƒ, ์˜ค๋””์˜ค ๋“ฑ ๋Œ€์šฉ๋Ÿ‰ ํŒŒ์ผ์„ ์—…๋กœ๋“œํ•  ๋•Œ, file ๊ฐ์ฒด๋ฅผ ์ด์šฉํ•œ๋‹ค. ์ด๋ฒˆ ํฌ์ŠคํŒ…์—์„œ๋Š” file ๊ฐ์ฒด์— ๋Œ€ํ•œ ๋‚ด์šฉ์„ ์ •๋ฆฌํ•ด๋ณด์•˜๋‹ค.

1. File ๊ฐ์ฒด

DOM input ์—˜๋ฆฌ๋จผํŠธ์˜ type ํ”„๋กœํผํ‹ฐ์˜ ๊ธฐ๋ณธ๊ฐ’์€ type=text ์ด๋‹ค. ์ด ๋•Œ, ์‚ฌ์šฉ์ž๋กœ๋ถ€ํ„ฐ ์ž…๋ ฅ๊ฐ’์„ string ํ˜•ํƒœ๋กœ ๋ฐ›๋Š”๋‹ค.๊ทธ๋Ÿผ ์‚ฌ์šฉ์ž๋กœ๋ถ€ํ„ฐ file์„ ์ž…๋ ฅ๋ฐ›์œผ๋ ค๋ฉด ์–ด๋–ป๊ฒŒ ํ• ๊นŒ? file์„ ์ž…๋ ฅ๋ฐ›์œผ๋ ค๋ฉด input ์—˜๋ฆฌ๋จผํŠธ์—ย type=file๋กœ ๋ช…์‹œํ•ด์ฃผ๋ฉด ๋œ๋‹ค.
์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅํ•œ ํŒŒ์ผ์— ์ ‘๊ทผํ•˜๋ ค๋ฉด input ์—˜๋ฆฌ๋จผํŠธ์— ์ ‘๊ทผํ•ด์„œ files ํ”„๋กœํผํ‹ฐ๋ฅผ ์ฐธ์กฐํ•˜๋ฉด ๋˜๋Š”๋ฐ, ์ง์ ‘ DOM์— ์ ‘๊ทผํ•ด์„œ ์ ‘๊ทผํ•  ์ˆ˜๋„ ์žˆ๊ณ , e.target ์„ ํ†ตํ•˜์—ฌ onChange ์ด๋ฒคํŠธํ•ธ๋“ค๋Ÿฌ๋ฅผ ๋“ฑ๋กํ•˜์—ฌ ์ž…๋ ฅ๋ฐ›์€ ๊ฐ’์„ ๊ฐ€์ ธ์˜ฌ ์ˆ˜๋„ ์žˆ๋‹ค.

1. ์ง์ ‘ DOM์— ์ ‘๊ทผํ•˜๋Š” ๋ฐฉ๋ฒ•

// ๋ฆฌ์•กํŠธ hooks ์‚ฌ์šฉ useEffect(() => { const fileElem = document.getElementById('fileInput') console.log(fileElem.files) }) return <input type="file" id="fileInput" />
๐Ÿ”ฝ ์ฝ˜์†” ์ถœ๋ ฅํ™”๋ฉด
notion imagenotion image

2.ย e.target์œผ๋กœ ์ด๋ฒคํŠธ๊ฐ€ ์ผ์–ด๋‚œ ์œ„์น˜ DOM ์ ‘๊ทผ

const handleImage = e => { console.log(e.target.files) } return <input type="file" id="fileInput" onChange={handleFiles} />
๐Ÿ”ฝ ์ฝ˜์†” ์ถœ๋ ฅํ™”๋ฉด
notion imagenotion image

ํŒŒ์ผ์„ ์—…๋กœ๋“œ ํ•œ ํ›„, file input ์—˜๋ฆฌ๋จผํŠธ์— ์ ‘๊ทผํ•ด์„œ files ํ”„๋กœํผํ‹ฐ๋ฅผ ์ถœ๋ ฅํ•ด๋ณด๋ฉดย fileListย ๋ผ๋Š” ๊ฐ์ฒด๊ฐ€ ์ถœ๋ ฅ๋˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. fileList ๊ฐ์ฒด ํ”„๋กœํผํ‹ฐ๋Š” 0,1 โ€ฆ ํ˜•ํƒœ์˜ ์ˆซ์ž๋กœ, ๊ทธ๋ฆฌ๊ณ  ๊ฐ’์—๋Š” File๊ฐ์ฒด๊ฐ€ ๋“ค์–ด์žˆ๋‹ค. ๊ทธ๋ž˜์„œ files[i] ์ด๋Ÿฐ ์‹์œผ๋กœ i ๋ฒˆ์งธ์˜ file ๊ฐ์ฒด์—๋„ ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.
FileList {0: File, length: 1}
๊ทธ๋Ÿผย file ๊ฐ์ฒด๋Š” ์–ด๋–ค ํ˜•ํƒœ๋กœ ์ด๋ฃจ์–ด์ ธ์žˆ์„๊นŒ? ๊ธฐ๋ณธ์ ์œผ๋กœ file ๊ฐ์ฒด๋Š” 4๊ฐ€์ง€ ์†์„ฑ์„ ๊ฐ€์ง„๋‹ค. ๋ชจ๋“  ์†์„ฑ์€ ์ฝ๊ธฐ์ „์šฉ์œผ๋กœ ์ฃผ์–ด์ง„๋‹ค.
const file = { lastModified: 1580961046732, lastModifiedDate: 'Thu Feb 06 2020 12:50:46 GMT+0900 (๋Œ€ํ•œ๋ฏผ๊ตญ ํ‘œ์ค€์‹œ) {}', name: 'dom.png', size: 192045, type: 'image/png', }

1๏ธโƒฃย lastModifiedย : ๋งˆ์ง€๋ง‰ ์ˆ˜์ • ๋‚ ์งœ numberํƒ€์ž…์œผ๋กœ ๋ฐ˜ํ™˜ (์—†์„ ๊ฒฝ์šฐ, ํ˜„์žฌ ์‹œ๊ฐ„)
2๏ธโƒฃย lastModifiedDateย : ๋งˆ์ง€๋ง‰ ์ˆ˜์ • ๋‚ ์งœ Date๊ฐ์ฒดํƒ€์ž…์œผ๋กœ ๋ฐ˜ํ™˜ (Deprecated)
Date ๊ฐ์ฒดํƒ€์ž…์„ ์ด์šฉํ•˜๊ณ  ์‹ถ์œผ๋ฉด, new Date(lastModified) ๋ฐฉ์‹์œผ๋กœ ์‚ฌ์šฉํ•˜๊ธฐ!!
3๏ธโƒฃย nameย : ๋‹จ์ˆœ ํŒŒ์ผ์˜ ์ด๋ฆ„ stringํƒ€์ž…์œผ๋กœ ๋ฐ˜ํ™˜ (๊ฒฝ๋กœ๋Š” ํฌํ•จํ•˜์ง€ ์•Š๋Š”๋‹ค.)
4๏ธโƒฃย sizeย : 64๋น„ํŠธ ์ •์ˆ˜์˜ ๋ฐ”์ดํŠธ ๋‹จ์œ„ ํŒŒ์ผ์˜ ํฌ๊ธฐ numberํƒ€์ž…์œผ๋กœ ๋ฐ˜ํ™˜
ํ•ด๋‹นํŒŒ์ผ์€ 192KB ํฌ๊ธฐ์ž„์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.
5๏ธโƒฃย typeย : ๋ฌธ์ž์—ด์ธ ํŒŒ์ผ์˜ย MIMEย ํƒ€์ž… stringํƒ€์ž…์œผ๋กœ ๋ฐ˜ํ™˜
MIME ํƒ€์ž…์˜ ํ˜•ํƒœ๋Š” type/subtype ์˜ ๊ตฌ์กฐ๋ฅผ ๊ฐ€์ง€๋ฉฐ, ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํ˜•ํƒœ๋กœ ์“ฐ์ธ๋‹ค.
text/plain text/html image/jpeg image/png audio/mpeg video/mp4 ...

2. URL๋กœ ์ ‘๊ทผ

์œ„์—์„œ๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅํ•œ File๊ฐ์ฒด์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์–ป๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณด์•˜๋‹ค. ๊ทธ๋Ÿผ File ๊ฐ์ฒด์˜ ์‹ค์ œ ๋ฐ์ดํ„ฐ์—๋Š” ์–ด๋–ป๊ฒŒ ์ ‘๊ทผํ• ๊นŒ?
๋จผ์ € file ๊ฐ์ฒด URL์„ ์ƒ์„ฑํ•ด์„œ ํ•ด๋‹น file์— ์ ‘๊ทผํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค. ์ด ๋ฐฉ๋ฒ•์€ window ๋ธŒ๋ผ์šฐ์ € ์ „์—ญ๊ฐ์ฒด์˜ URL ์†์„ฑ์˜ ๋ฉ”์†Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.
const img = document.createElement('img') img.src = window.URL.createObjectURL(files[0]) img.onload = function() { window.URL.revokeObjectURL(this.src) }

1๏ธโƒฃย createObjectURL()ย : ์ธ์ž๋กœ File๊ฐ์ฒด๋ฅผ ๋ฐ›์œผ๋ฉฐ, ํ•ด๋‹น file์˜ ๊ณ ์œ  URL ์ •๋ณด ์ƒ์„ฑํ•˜๊ณ  ๋ฐ˜ํ™˜ํ•œ๋‹ค.
2๏ธโƒฃย revokeObjectURL()ย : file์ด ๋กœ๋“œ๊ฐ€ ์™„๋ฃŒ๋˜์—ˆ์„ ์‹œ, ๋”์ด์ƒ URL์ •๋ณด๋Š” ์‚ฌ์šฉ๋˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๋ฅผ ๋ง‰๊ธฐ ์œ„ํ•ด ํ•ด์ฒดํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.

URL๋กœ ์ ‘๊ทผ ํ•˜๋Š” ๊ฒฝ์šฐ, ์ฃผ์š” ํŠน์ง•์œผ๋กœ๋Š”
๐ŸŽ. URL์„ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— ๋™๊ธฐ์ ์œผ๋กœ ์‹คํ–‰๋˜๋ฉฐ ์‹œ๊ฐ„์ด ๋น ๋ฅด๋‹ค.
๐ŸŽ. ํ•˜์ง€๋งŒ URL์ด ์‚ฌ์šฉ๋˜์—ˆ์œผ๋ฉด ์ˆ˜๋™์ ์œผ๋กœ ํ•ด์ฒดํ•ด์ฃผ์–ด์•ผํ•˜๋Š” ๋‹จ์ ์ด ์žˆ๋‹ค.

3. FileReader๋กœ ์ ‘๊ทผ

๋˜๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์€ FileReader ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ธ๋ฐ, FileReader ๊ฐ์ฒด๋Š” ๋น„๋™๊ธฐ์ ์œผ๋กœ file์„ ์ฝ๊ณ  ์ €์žฅํ•˜๋Š” ๊ฒƒ์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ด์ค€๋‹ค.
์œ„์˜ URL๋กœ ์ ‘๊ทผํ•˜๋Š” ๋ฐฉ๋ฒ•๊ณผ ๋น„๊ตํ–ˆ์„ ๋•Œ, ์ด๋Ÿฌํ•œ ํŠน์ง•์„ ๊ฐ€์ง„๋‹ค.
๐ŸŽ. ๋น„๋™๊ธฐ์ ์œผ๋กœ ์‹ค์ œ file์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ๊ธฐ ๋•Œ๋ฌธ์—, ์‹œ๊ฐ„์ด ๋Š๋ฆฌ๊ณ  ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰๋„ ๋†’๋‹ค.
๐ŸŽ. ํ•˜์ง€๋งŒ ์ˆ˜๋™์œผ๋กœ ํ•ด์ฒดํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค.(๊ฐ€๋น„์ง€ ์ปฌ๋ ‰ํ„ฐ์— ์˜ํ•ด ์ž๋™์œผ๋กœ ํ•ด์ฒด)
FileReader ๊ฐ์ฒด์˜ ๋ฉ”์†Œ๋“œ๋Š” 5๊ฐ€์ง€๊ฐ€ ์กด์žฌํ•œ๋‹ค.

1๏ธโƒฃย FileReader.abort()ย : ํŒŒ์ผ ์ฝ๊ธฐ๋ฅผ ์ค‘๋‹จํ•จ.
2๏ธโƒฃย FileReader.readAsArrayBuffer()ย : ํŒŒ์ผ์„ ์ฝ๊ณ , result์†์„ฑ์— ํŒŒ์ผ์˜ ArrayBuffer ํ˜•ํƒœ๋ฅผ ์ €์žฅ.
๋ฐ์ดํ„ฐ๋ฅผ ์ผ์ •ํ•œ ํฌ๊ธฐ๋กœ ์ž˜๋ผ ์„œ๋ฒ„๋กœ ๋ณด๋‚ผ ๋•Œ ์‚ฌ์šฉ.
3๏ธโƒฃย FileReader.readAsBinaryString()ย : ํŒŒ์ผ์„ ์ฝ๊ณ , result์†์„ฑ์— ํŒŒ์ผ์˜ ์›์‹œ ์ด์ง„ ๋ฐ์ดํ„ฐ ํ˜•ํƒœ๋ฅผ ์ €์žฅ.
4๏ธโƒฃย FileReader.readAsDataURL()ย : ํŒŒ์ผ์„ ์ฝ๊ณ , result์†์„ฑ์— ํŒŒ์ผ์„ ๋‚˜ํƒ€๋‚ด๋Š” URL์„ ์ €์žฅ.
5๏ธโƒฃย FileReader.readAsText()ย : ํŒŒ์ผ์„ ์ฝ๊ณ , result์†์„ฑ์— ํŒŒ์ผ์˜ ํ…์ŠคํŠธ ๋ฌธ์ž์—ด ํ˜•ํƒœ๋ฅผ ์ €์žฅ.

๊ทธ๋ฆฌ๊ณ  FileReader๋Š” ๋น„๋™๊ธฐ ๋งค์ปค๋‹ˆ์ฆ˜์„ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ์ด๋ฒคํŠธํ•ธ๋“ค๋Ÿฌ๋ฅผ ๋“ฑ๋กํ•˜์—ฌ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ๋‹ค. ์ด 6๊ฐœ์˜ ์ด๋ฒคํŠธํ•ธ๋“ค๋Ÿฌ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
1๏ธโƒฃย FileReader.onabortย : ์ฝ๊ธฐ ์ค‘๋‹จ ์‹œ, ํŠธ๋ฆฌ๊ฑฐ ๋จ.
2๏ธโƒฃย FileReader.onerrorย : ์ฝ๋Š” ๋„์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ์‹œ, ํŠธ๋ฆฌ๊ฑฐ ๋จ.
3๏ธโƒฃย FileReader.onloadย : ์ฝ๊ธฐ ์™„๋ฃŒ ์‹œ(์„ฑ๊ณต๋งŒ), ํŠธ๋ฆฌ๊ฑฐ ๋จ.
4๏ธโƒฃย FileReader.onloadstartย : ์ฝ๊ธฐ ์‹œ์ž‘ ์‹œ, ํŠธ๋ฆฌ๊ฑฐ ๋จ.
5๏ธโƒฃย FileReader.onloadendย : ์ฝ๊ธฐ ์™„๋ฃŒ ์‹œ(์„ฑ๊ณต,์‹คํŒจ), ํŠธ๋ฆฌ๊ฑฐ ๋จ.
6๏ธโƒฃย FileReader.onprogressย : ์ฝ๋Š” ๋„์ค‘, ํŠธ๋ฆฌ๊ฑฐ ๋จ.

์ด๋Ÿฌํ•œ ์ด๋ฒคํŠธํ•ธ๋“ค๋Ÿฌ์™€ ๋ฉ”์†Œ๋“œ๋ฅผ ์ด์šฉํ•ด์„œ, ํŒŒ์ผ์˜ ์‹ค์ œ ๋ฐ์ดํ„ฐ์— ์ ‘๊ทผํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.
const reader = new FileReader() reader.onload = (event: any) => { console.log('reader', event.target.result) } reader.readAsDataURL(e.target.files[0])
์ฝ”๋“œ์˜ ํ๋ฆ„์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค. โ€œFileReader ๊ฐ์ฒด ์ธ์Šคํ„ด์Šค reader๋ฅผ ์ƒ์„ฑ > onload ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ๋“ฑ๋ก > readAsDataURL() ๋ฉ”์†Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ํ•ด๋‹น ํŒŒ์ผ์„ ์ฝ์Œ > onload ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ํŠธ๋ฆฌ๊ฑฐ ๋จ > ํ•ด๋‹น ํŒŒ์ผ์˜ result ์†์„ฑ๊ฐ’ ์ถœ๋ ฅ
notion imagenotion image
์‹ค์ œ ์ด๋Ÿฌํ•œ ๊ฐ’์œผ๋กœ ์ถœ๋ ฅ๋˜๋ฉฐ, img.src ๊ฐ’์œผ๋กœ ๋„ฃ์–ด์„œ ์‚ฌ์šฉ๋„ ๊ฐ€๋Šฅํ•˜๋‹ค. ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์˜ฌ๋ฆฐ ํŒŒ์ผ์„ ๋‹ค์‹œ ๋‹ค์šด๋กœ๋“œํ•˜๋Š” ๊ฒƒ๋„ ์ด๋Ÿฌํ•œ data URL์„ ์ด์šฉํ•˜๋ฉด ๋œ๋‹ค.

4. Blob ๊ฐ์ฒด

์ง€๊ธˆ๊นŒ์ง€ File ๊ฐ์ฒด์˜ ์ฝ๊ธฐ์ „์šฉ ์†์„ฑ๋“ค๊ณผ, URL๋กœ ์ ‘๊ทผ ํ˜น์€ FileReader๊ฐ์ฒด ๋ฉ”์†Œ๋“œ๋ฅผ ์ด์šฉํ•ด์„œ ์ ‘๊ทผํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณด์•˜๋Š”๋ฐ, ๊ทธ๋Ÿผ ์‚ฌ์šฉ์ž๋กœ๋ถ€ํ„ฐ ์ž…๋ ฅ๋ฐ›์€ file์„ ๋‹ค๋ฅธ ๊ณณ์œผ๋กœ ์ „์†กํ•˜๋ ค๋ฉด ์–ด๋–ป๊ฒŒ ํ• ๊นŒ? ์ด๋Ÿด ๋•Œ๋Š” Blob (Binary large object)๊ฐ์ฒด๋ฅผ ์ด์šฉํ•˜๋ฉด ๋œ๋‹ค.
์‚ฌ์‹ค File ์ธํ„ฐํŽ˜์ด์Šค๋„ ์‚ฌ์šฉ์ž์—๊ฒŒ file์˜ ํ˜•ํƒœ๋ฅผ ์ž…๋ ฅ๊ฐ’์œผ๋กœ ๋ฐ›๊ธฐ ์œ„ํ•ด์„œ Blob ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ™•์žฅํ•œ ๊ฒƒ์ด๊ณ , ๋ชจ๋“  blob ๊ธฐ๋Šฅ์„ ์ƒ์†ํ•œ๋‹ค. ๊ทธ๋ž˜์„œ blob๊ฐ์ฒด๋„ file๊ฐ์ฒด์™€ ๋น„์Šทํ•œ ํ˜•ํƒœ๋ฅผ ๊ฐ€์ง„๋‹ค.
console.log(e.target.files[0] instanceof File) // true console.log(e.target.files[0] instanceof Blob) // true
blob์€ file๊ฐ์ฒด์˜ name, lastModified ์†์„ฑ์ด ์—†๊ณ  size์™€ type(MIME)์†์„ฑ๋งŒ ๊ฐ–๋Š”๋‹ค.
const blob = { // lastModified: 1580961046732, // lastModifiedDate: 'Thu Feb 06 2020 12:50:46 GMT+0900 (๋Œ€ํ•œ๋ฏผ๊ตญ ํ‘œ์ค€์‹œ) {}', // name: 'dom.png', size: 192045, type: 'image/png', }
๊ทธ๋Ÿผ ์–ด๋–ป๊ฒŒ blob๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ด์„œ ๋‹ค๋ฅธ ๊ณณ์œผ๋กœ ์ „์†กํ• ๊นŒ?
์œ„์—์„œ File๊ฐ์ฒด์˜ ์‹ค์ œ ๋ฐ์ดํ„ฐ์—ย FileReader.readAsDataURL()๋ฅผ ํ†ตํ•˜์—ฌ ์ ‘๊ทผํ–ˆ์„ ๋•Œ, ์ด๋Ÿฐ์‹์˜ URL ๊ฐ’์ด ์ถœ๋ ฅ๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.
notion imagenotion image
์ด๋Ÿฌํ•œ URLํ˜•ํƒœ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์ƒˆ๋กœ์šด blob ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•ด์„œ ๋‹ค๋ฅธ ๊ณณ์œผ๋กœ ์ „์†กํ•˜๋ฉด ๋œ๋‹ค.
์ฝ”๋“œ๊ฐ€ ๊น”๋”ํ•ด์„œ ์ดํ•ดํ•˜๊ธฐ ์‰ฌ์› ๋‹ค.
const dataURLToBlob = dataURL => { const BASE64_MARKER = ';base64,' // base64๋กœ ์ธ์ฝ”๋”ฉ ๋˜์–ด์žˆ์ง€ ์•Š์„ ๊ฒฝ์šฐ if (dataURL.indexOf(BASE64_MARKER) === -1) { const parts = dataURL.split(',') const contentType = parts[0].split(':')[1] const raw = parts[1] return new Blob([raw], { type: contentType, }) } // base64๋กœ ์ธ์ฝ”๋”ฉ ๋œ ์ด์ง„๋ฐ์ดํ„ฐ์ผ ๊ฒฝ์šฐ const parts = dataURL.split(BASE64_MARKER) const contentType = parts[0].split(':')[1] const raw = window.atob(parts[1]) // atob()๋Š” Base64๋ฅผ ๋””์ฝ”๋”ฉํ•˜๋Š” ๋ฉ”์„œ๋“œ const rawLength = raw.length // ๋ถ€ํ˜ธ ์—†๋Š” 1byte ์ •์ˆ˜ ๋ฐฐ์—ด์„ ์ƒ์„ฑ const uInt8Array = new Uint8Array(rawLength) // ๊ธธ์ด๋งŒ ์ง€์ •๋œ ๋ฐฐ์—ด let i = 0 while (i < rawLength) { uInt8Array[i] = raw.charCodeAt(i) i++ } return new Blob([uInt8Array], { type: contentType, }) }

5. ๋งˆ์น˜๋ฉฐ

์ด๋ฒˆ ํฌ์ŠคํŒ…์œผ๋กœ ์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅํ•œ file์„ ์ ‘๊ทผํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋‘๊ฐ€์ง€๋กœ ์•Œ์•„๋ณด์•˜๊ณ , ๋‹ค์‹œ ์žฌ์ „์†ก๋  ์ˆ˜ ์žˆ๋Š” blob๊ฐ์ฒด๋กœ ๋งŒ๋“œ๋Š” ๋ฒ•๊นŒ์ง€ ์•Œ์•„๋ณด์•˜๋‹ค.
ํ”„๋ก ํŠธ์—”๋“œ๋Š” ์‚ฌ์šฉ์ž๋กœ ํ•˜์—ฌ๊ธˆ View์—์„œ ๋„˜์–ด์˜ค๋Š” action๋“ค์„ ์ฒ˜๋ฆฌํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ์—ฌ๋Ÿฌ ๋‹ค์–‘ํ•œ ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๊ณ , ๋˜ํ•œ ์š”์ฒญํ•˜๋Š” ๋ฐ์ดํ„ฐ์˜ ํ˜•ํƒœ๋„ ๋‹ค์–‘ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋Ÿฌํ•œ action์„ ์ ์ ˆํžˆ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒƒ๋„ ํ”„๋ก ํŠธ์—”๋“œ ๊ฐœ๋ฐœ์ž์˜ ์—ญ๋Ÿ‰ ์ค‘ ํ•˜๋‚˜๊ฐ€ ์•„๋‹๊นŒ ๋‹ค์‹œํ•œ๋ฒˆ ์ƒ๊ฐํ•ด๋ณด์•˜๋‹ค.

6. reference

Loading Comments...