로컬파일에서 업로드한 파일의 정보를 백엔드로 보내주면 백엔드에서 데이터베이스의 이미지를 해당 이미지로 바꿔주어야 했다.
우리가 생각했던 방법은 크게 2가지였다.
그리고 이 이미지를 전달해주는 방법에 대해서도 고민 포인트가 있었다.
이미지 전달 방법을 백엔드 팀원분과 함께 맞추려고 하다가, base64에 대해 알게 되었다.
문자열이 3개씩 나누어떨어지지 않을 경우 padding이라는 개념으로, 남는 자리를 =기호를 사용해 채워주어 빈 자리를 명시한다.
인코딩이 그래서 정확히 뭘까?
정보의 형태/형식을 여러가지 목적에 따라 다른 형태/형식으로 변환하는 처리
Base64를 사용하면 Binary데이터를 텍스트 기반 규격으로 다룰 수 있다.
JSON과 같은 문자열 기반 데이터 안에 이미지 파일 등을 Base64로 인코딩하면 UTF-8과 호환 가능한 문자열을 얻을 수 있다.
기존 ASCII코드는 시스템간 데이터를 전달하기에 안전하지 않다. 모든 Binary 데이터가 ASCII코드에 포함되지 않으므로 제대로 읽을 수 없는 문자가 있을 수 있기 때문이다.
반면 Base64는 ASCII 중 제어문자와 일부 특수문자를 제외한 53개의 안전한 출력문자만 이용하기 때문에 데이터 전달에 더 적합하다.
const reader = new FileReader();
const uploadedFile = e.target.files[0];
reader.readAsDataURL(uploadedFile);
reader.onload = function (e) {
const encodedImg = e.target.result;
FormData 객체안에 이미 키가 존재하면 그 키에 새로운 값을 추가하고, 키가 없으면 추가합니다.
FormData 객체로부터 키/밸류 쌍을 삭제합니다.
이 객체에 담긴 모든 키/밸류 쌍을 순회할 수 있는 iterator를 반환합니다.
FormData 객체 내의 값들 중 주어진 키와 연관된 첫번째 값을 반환합니다.
FormData 객체 내의 값들 중 주어진 키와 연관된 모든 값이 담긴 배열을 반환합니다.
FormData 객체에 특정 키가 포함되어 있는지 여부를 나타내는 boolean 을 반환합니다.
이 객체에 담긴 모든 키/벨류 쌍들의 모든 키들을 순회 할 수 있는 iterator를 반환합니다.
FormData 객체 내에 있는 기존 키에 새 값을 설정하거나, 존재하지 않을 경우 키/밸류 쌍을 추가합니다.
이 객체에 포함된 모든 밸류를 통과하는 iterator를 반환합니다.
formData는 콘솔에 출력되지 않는다.
console.log(formData)
를 했다가 빈 값이 출력되어 코드의 어떤 부분이 잘못되었는지 고민하느라 꽤 오랜 시간을 보냈을 때쯤에 알게된 것은, formData는 일반적인 콘솔출력문으로 내부 값을 출력할 수 없다는 것이다. 확인하려면 다음과 같은 방법으로 출력할 수 있다.
for (var value of formData.values()) {
console.log(value);
}
formData를 body에 보낼때는 content type을 헤더에 명시하지 않는다.
백엔드와 통신하면서 애먹었던 부분이다.
아무리 보내도 백엔드에는 요청은 성공했지만 body에 담긴 값은 도달하지않았다.
그 때의 코드는 이렇다.
async function submitPrice() {
const formData = new FormData();
formData.append('price', price);
await fetch(
`url`,
{
method: 'POST',
headers: {},
body: {
'price': formData,
},
}
)
}
다시 JSON.stringify를 사용해보기도 했다.
body: JSON.stringify{
'price': formData,
},
formData에 대해 제대로 알지 못해서 이런 고민을 했다.
객체에 담을 필요도, JSON변환할 필요도 없이 body에 그대로 담아주면된다. (이리 저리 찾아보면서 참고했던 다른 코드들은 body객체에 담아주었던데..그건 뭘까..?)
호텔의 가격정보를 변경하는 함수는 이렇게 작성했다.
async function submitPrice() {
const formData = new FormData();
formData.append('price', price);
await fetch(
`url`,
{
method: 'POST',
headers: {},
body: formData,
//formData는 객체 내부에 담아 보내지 않고,
//그대로 body에 작성한다. JSON.stringify를 사용할 필요도 없다.
}
)
}
formData에 대해 제대로 알지 못하고 무작정 써보았는데, formData의 장점을 제대로 살리지 못했다는 생각이 들었다.
formData의 장점 중 하나는 form태그없이도 append를 사용해 key:value형태로 여러 인풋값을 저장해 한번에 보낼 수 있다는 것인데, 구현한 어드민 페이지는 막상 각 호텔의 가격/이미지 정보를 변경할 때마다 요청을 보내도록되어있었기 때문이다.