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

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ ์ด๋ฏธ์ง€๋‚˜ ๋™์˜์ƒ, ์˜ค๋””์˜ค ๋“ฑ ๋Œ€์šฉ๋Ÿ‰ ํŒŒ์ผ์„ ์—…๋กœ๋“œํ•  ๋•Œ, 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" />

๐Ÿ”ฝ ์ฝ˜์†” ์ถœ๋ ฅํ™”๋ฉด

fileconsole1

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

const handleImage = e => {
  console.log(e.target.files)
}

return <input type="file" id="fileInput" onChange={handleFiles} />

๐Ÿ”ฝ ์ฝ˜์†” ์ถœ๋ ฅํ™”๋ฉด

fileconsole2


ํŒŒ์ผ์„ ์—…๋กœ๋“œ ํ•œ ํ›„, 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 ์†์„ฑ๊ฐ’ ์ถœ๋ ฅ

filereader1

์‹ค์ œ ์ด๋Ÿฌํ•œ ๊ฐ’์œผ๋กœ ์ถœ๋ ฅ๋˜๋ฉฐ, 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 ๊ฐ’์ด ์ถœ๋ ฅ๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.

filereader1

์ด๋Ÿฌํ•œ 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

https://developer.mozilla.org/ko/docs/Web/API/File

https://stackoverflow.com/questions/31742072/filereader-vs-window-url-createobjecturl

https://developer.mozilla.org/ko/docs/Web/API/Blob

https://feel5ny.github.io/2018/05/27/JS_12/


Written by@taenyKim
์›น ํ”„๋ก ํŠธ์—”๋“œ ๊ณต๋ถ€ ๋ธ”๋กœ๊ทธ / Learn in Public

GitHubFacebook