프론트쪽에서 서버에 데이터를 보낼 때, 데이터 중 파일 객체 데이터가 포함되어있다면 특정 작업들을 추가적으로 해줘야한다.
특정 작업들이란 크게 두가지이다.
mulitpart/form-data
axios.post("www.test.com",{
'Content-Type': 'multipart/form-data'
})
client.patch('/member/mypage', createFormData(params), formHeaders)
기본적으로 서버에 데이터를 보낼 때, content-type은 json으로 보내준다.
application/json
axios.post("www.test.com",{
'Content-Type': 'application/json'
})
기본적으로 프로젝트에서 axios 서버 통신 파일을 세팅할 때, json으로 설정해준다.
그래서 만약 특정 API를 요청할 때, header를 mulitpart/form-data로 변경해야한다면 요청 메서드의 세번째 인자에 담아 보내줘야한다.
export const formHeaders = {
headers: {
'Content-Type': 'multipart/form-data',
},
};
client.patch('/member/mypage', data, formHeaders)
여기서 헤더만 변경하는 것이 아니라 보내는 데이터를 formData로 변환해줘야하는 작업이 추가로 필요하다.
예를 들어서, 서버로 보내는 데이터가 다음과 같다고 해보자.
const data ={
name :"jev",
email:"test@test.com",
profile : new File() // 임의로 파일 객체 설정(유효한 코드 아님)
}
client.patch('/member/mypage', data, formHeaders)
이 때, 위와 같이 보내면 415(Unsupported Media Type)에러가 발생할 것이다.
이유는 data를 formData로 변경해주지 않아서이다.
data를 formData를 변경하기 위해서는 다음과 같이 하면 된다.
// 서버로 보낼 데이터
const data ={
name :"jev",
email:"test@test.com",
profile : new File() // 임의로 파일 객체 설정(유효한 코드 아님)
}
// 데이터를 formData로 변환해주는 함수
function createFormData(data){
const form = new FormData();
form.append("name",data.name);
form.append("email",data.email);
form.append("profile",data.profile)
return form
}
// API 요청
client.patch('/member/mypage', createFormData(data), formHeaders)
위와 같이 해주면 요청이 성공적으로 된다.
사내 프로젝트를 진행하면서 서버로 보내줘야하는 데이터의 형태가 다음과 같았다.
const data = {
file : new File(), // 임의로 파일 객체 설정(유효한 코드 아님)
request:{
name :"jev",
email:"test@test.com"
}
}
데이터가 두개의 key값을 가지는데 file key에 대한 값을 파일 객체, request key에 대한 값은 객체의 형태이다.
그렇다면 위에서 한 방법대로 formData로 변경해주면 되겠다싶어 다음과 같이 변경해줬다.
export const formHeaders = {
headers: {
'Content-Type': 'multipart/form-data',
},
};
// 서버로 보낼 데이터
const data = {
file : new File(), // 임의로 파일 객체 설정(유효한 코드 아님)
request:{
name :"jev",
email:"test@test.com"
}
}
// 데이터를 formData로 변환해주는 함수
function createFormData(data){
const form = new FormData();
form.append("file",data.file);
form.append("request",data.request);
formData.append(
"request",
new Blob([JSON.stringify(postData.request)], {
type: "application/json",
})
);
return form
}
// API
client.post(`event`, createFormData(data), formHeaders);
하지만 위와 같이 요청을 하면 에러가 발생한다.
결론적으로 우선 다음과 같은 형태로 데이터를 보내줘야한다.
export const formHeaders = {
headers: {
'Content-Type': 'multipart/form-data',
},
};
// 서버로 보낼 데이터
const data = {
file : new File(), // 임의로 파일 객체 설정(유효한 코드 아님)
request:{
name :"jev",
email:"test@test.com"
}
}
// 데이터를 formData로 변환해주는 함수
function createFormData(data){
const form = new FormData();
form.append("file",data.file);
form.append(
"request",
new Blob([JSON.stringify(data.request)], {
type: "application/json",
})
);
return form
}
// API
client.post(`event`, createFormData(data), formHeaders);
우선 formdata를 서버에 데이터를 전송할 때에, 일반 텍스트 데이터라면 그냥 전송해도 되지만 데이터가 객체라면 이를 이진 데이터로 처리하여 보내줘야한다.
텍스트 데이터
// success
const data = "jev"
const form = new FormData()
form.append("data",data)
객체 데이터
// failure
const data = {
name :"jev"
}
const form = new FormData()
form.append("data",data)
자바스크립트 객체는 텍스트가 아닌 이진 데이터이기 때문에, 이를 이진 형태로 전송해야한다.
Blob을 사용하면 이진 데이터를 효과적으로 전송할 수 있다.
Blob
Blob은 이진 형식의 데이터이다.
new Blob()을 통해 이진 데이터를 생성하거나 이진 데이터로 변환해줄 수 있다.
그리고 new Blob으로 데이터를 처리할 때, 일반 객체 데이터를 담을 경우 이를 문자열화해줘야하기 때문에 위와 같이 처리해주는 것이다.
export const formHeaders = {
headers: {
'Content-Type': 'multipart/form-data',
},
};
// 서버로 보낼 데이터
const data = {
file : new File(), // 임의로 파일 객체 설정(유효한 코드 아님)
request:{
name :"jev",
email:"test@test.com"
}
}
// 데이터를 formData로 변환해주는 함수
function createFormData(data){
const form = new FormData();
form.append("file",data.file);
form.append("request",data.request);
formData.append(
"request",
new Blob([JSON.stringify(postData.request)], {
type: "application/json",
})
);
return form
}
// API
client.post(`event`, createFormData(data), formHeaders);
서버에 데이터를 보낼 때에, 파일이 있는 경우 원시 데이터뿐만 아니라 객체도 보내는 경우가 많으니 참고하도록 하자.
근데 글을보니까 어떤건 postData고 어떤건 data고 구분이 잘안가네용.. 혹시 오타인가요??
form.append("file",data.file);
form.append("request",data.request);
formData.append(
"request",
new Blob([JSON.stringify(postData.request)], {
type: "application/json",
})
);
이거는 왜 두번하는지 궁금합니다! 그리고 postData인지도..