👌
base64の画像をフォームで送るためのFileにする方法
経緯
画像を加工したのち、DBや、ストレージに保存したい ということで、バックエンドにフォームを送る際、Fileにしないといけなかった。
画像加工後はbase64になっているのでそれをFileクラスでラップするにはどうすればいいかで少し詰まったので備忘録。
結論から言うと、一度バイナリにしないといけなく、base64 => バイナリへの作業が必要になった。
画像をbase64にする
<div>
<input type='file' onchange='convertToBase64()'>
<img src='' />
</div>
function convertToBase64 () {
const file = document.querySelector('input[type=file]').files[0]
const preview = document.querySelector('img');
const reader = new FileReader()
reader.addEventListener('load', e => {
preview.src = reader.result;
})
if (file) {
reader.readAsDataURL(file);
}
}
FileをFormにして送信する
Formにする
function convertToForm () {
const $inputFile = document.querySelector('input[type=file]').files[0]
const $img = document.querySelector('img')
const imgData = $img.src
const imgFile = _convertToFile(imgData, $inputFile)
const fd = new FormData()
fd.append('image', imgFile)
console.log(fd.get('image')); // File情報
// fileを送信
fetch('URL', {
method: 'POST',
body: fd
})
}
Fileにする
function _convertToFile (imgData, file) {
// ここでバイナリにしている
const blob = atob(imgData.replace(/^.*,/, ''));
let buffer = new Uint8Array(blob.length);
for (let i = 0; i < blob.length; i++) {
buffer[i] = blob.charCodeAt(i);
}
return new File([buffer.buffer], file.name, {type: file.type});
}
全体コード
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div>
<input type='file' onchange='convertToBase64()'>
<button onclick='convertToForm()'>送信</button>
<img src="" alt="">
</div>
<script lang='js'>
function convertToBase64 () {
const file = document.querySelector('input[type=file]').files[0]
const preview = document.querySelector('img');
const reader = new FileReader()
reader.addEventListener('load', () => {
preview.src = reader.result;
})
if (file) {
reader.readAsDataURL(file);
}
}
function convertToForm () {
const $inputFile = document.querySelector('input[type=file]').files[0]
const $img = document.querySelector('img')
const imgData = $img.src
const imgFile = _convertToFile(imgData, $inputFile)
const fd = new FormData()
fd.append('image', imgFile)
console.log(fd.get('image')); // File情報
// fileを送信
fetch('URL', {
method: 'POST',
body: fd
})
}
function _convertToFile (imgData, file) {
// ここでバイナリにしている
const blob = atob(imgData.replace(/^.*,/, ''));
let buffer = new Uint8Array(blob.length);
for (let i = 0; i < blob.length; i++) {
buffer[i] = blob.charCodeAt(i);
}
return new File([buffer.buffer], file.name, {type: file.type});
}
</script>
</body>
</html>
参考
Discussion