blob : 이미지 file을 업로드할 경우, 브라우저에서만 임시로 이미지를 보여줄 수 있도록 메모리에 저장하는 임시 url 형식이 blob이다.
예시 :
blob:Url 이 형식은 언뜻 보면 이미지 주소로 변환된 것 같지만, 서버에 보낼 수 있는 일반적인 url이 아니다. 브라우저에서 임시로 이미지를 보여주도록 만든 blob형식이기 때문에 blob형식 자체를 서버에 보낼 경우 이미지 주소가 저장되거나, 파일이 저장되지 않는다.
회원정보 수정 로직의 경우, 대체로 백엔드에 request로 이미지 파일 자체를 보낸다.
-> 백엔드에서는 파일을 저장, 파일의 이미지 주소 url을 response로 프론트에 전달해준다. (서버의 회원 정보에도 이미지 url로 저장)
-> 프론트에서 변경된 이미지를 보여주는 경우 해당 이미지 주소를 받아 보여주게 된다.
백엔드로 프로필 이미지를 보낼 때는 : file 자체를 보낸다. (이미지 파일)
일반적으로 formData에 담아서 보내기 때문에, 닉네임과 프로필 이미지를 함께 formData에 담아 formData 자체를 request로 보내면 된다.
// ✅ 한달인턴 과제
// src > apis > myPageApi.ts
export const updateUserInfo = async (newUserInfo: UpdateUserInfoRequest) => {
const formData = new FormData();
console.log("newUserInfo.avatar", newUserInfo.avatar);
formData.append("avatar", newUserInfo.avatar);
formData.append("nickname", newUserInfo.nickname);
// ⭐️ axios instance에서 공통 header를 설정해놓았다면,
// formData를 보낼 때는 header를 동적으로 명시해야 한다.
const response = await api.patch("/profile", formData, {
headers: {
"Content-Type": "multipart/form-data",
},
});
return response;
};
// ✅ 공통 axios instance
// src > apis > axiosInstance.ts
import axios from "axios";
const api = axios.create({
baseURL: import.meta.env.VITE_API_BASE_URL,
timeout: 10000,
headers: {
"Content-Type": "application/json",
},
});
api.interceptors.request.use(
(config) => {
const token = localStorage.getItem("accessToken");
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
},
(error) => Promise.reject(error)
);
export default api;
const handleImageChange = async (e: React.ChangeEvent<HTMLInputElement>) => {
if (e.target.files && e.target.files[0]) {
const file = e.target.files[0];
const imageUrl = URL.createObjectURL(file);
console.log("Blob URL:", imageUrl);
// Base64로 변환
const base64 = await convertBlobToBase64(file);
console.log("Base64:", base64);
// 상태에 저장하거나 서버로 전송 준비
setProfileImage(base64);
}
};
📝 예전에 부트캠프하면서 과제 수행에만 급급할 때는 blob이 뭔지, formData는 뭔지, 이미지 파일 자체를 전달하는 건지, blob도 이미지 주소처럼 보이는데 왜 얘는 주소가 아니라고 하는지 이해도 안되고 시간도 없으니 그냥 gpt가 하라는 대로 오류 해결에만 급박했다. 하지만 천천히 이해하며 코드를 작성하고 있으니 그 때는 안보이던 것들이 보이기 시작하는 것 같다.