form에 이미지 파일 전송하기
form 태그에 이미지 파일과 text 데이터를 담은 json을 넣어서 php 서버로 request 하고 response를 받아보자
1. 이미지 파일 업로드, 변수에 저장하기
-> 일반적인 문자, 숫자와 다르게 이미지, 동영상 등의 미디어 파일이나 json 형태의 데이터를 원본 그대로 전송하고 싶다면, blob 객체로 만들어서 전송해야한다.
<input type="text" name="Text1" id="text1">
<input type="text" name="Text2" id="text2">
<input type="file" name="Img" id="userImg" accept="image/*" multiple>
이미지를 가져오려면 input에 file 타입을 선언하고 파일의 형식을 accept에 지정해줘야한다.
multiple 속성을 선언하면 여러개의 파일을 가져올 수 있다.
const text1 = document.querySelector("#text1");
const text2 = document.querySelector("#text2");
const userImg = document.querySelector("#userImg");
let selectedImages;
userImg.addEventListener("change", function() {
selectedImages = userImg.files;
for (let i = 0; i < selectedImages.length; i++) {
let selectedImage = selectedImages[i];
if (!selectedImage.type.startsWith('image/')) {
alert('이미지 파일만 업로드할 수 있습니다.');
userImg.value = '';
return;
}
}
}
userImg,files를 이용하면 userImg 태그에 있는 파일들을 모두 가져올 수 있다. 각각의 파일들은 객체로 되어있다
2. form 태그 작성 및 XMLHttpRequest 보내기
Btn.addEventListener("click", function(e) {
e.preventDefault();
let xmlHttpRequest = new XMLHttpRequest();
// response 처리용 함수
xmlHttpRequest.onreadystatechange = function() {
try {
if (xmlHttpRequest.readyState === 4) {
if (xmlHttpRequest.status === 200) {
console.log('response 성공');
} else {
console.log('response 실패');
}
}
} catch (e) {
console.log('Caught Exception: ' + e.description);
}
};
// form 작성
const form = new FormData();
form.append('userImg', selectedImages[0]);
const stringDataDto = JSON.stringify({
text1: text1.value,
text2: text2.value
});
form.append('stringDataDto', new Blob([stringDataDto], {
type: 'application/json'
}));
xmlHttpRequest.responseType = 'blob';
xmlHttpRequest.open('POST', 'Img.php', true);
xmlHttpRequest.send(form);
}
-> XMLHttpsRequest를 전송하고 받으려면, onreadystatechange 이벤트를 가진 함수를 선언해야한다.
request를 전송한 다음 response를 받으면 해당 함수를 실행한다.
또 js에서 form을 생성했는데, 이미지와 같은 file 이나 json같은 데이터를 전송하고싶다면 blob 과 같은 객체 형태로 변경해서 type을 지정해서 보낼 수 있다.
request의 바디에는 다음과 같이 WebKitForm 내부에 blob 형태의 json과 image/png 가 들어가있는 것을 확인할 수 있다.
3. php에서 response 보내기
<?php
if ($_SERVER["REQUEST_METHOD"] == "POST") {
$imgFilePath = $_FILES['userImg']['tmp_name'];
$stringDataDto = $_FILES['stringDataDto']['tmp_name'];
$stringData = file_get_contents($stringDataDto);
$img = imagecreatefrompng($imgFilePath);
//
파일 처리
//
header("Content-Type: image/jpeg");
imagepng($img);
imagedestroy($img);
}
request를 post 방식으로 전송했기 때문에, php에서 $_SERVER 슈퍼 변수에 REQUEST_METHOD가 어떤건지 확인한다.
$_FILES 변수에 request body에 담았던 파일들이 임시파일로 저장되어 있기 때문에, 임시파일의 경로로 부터 파일을 저장해서 사용할 수 있다.
php에서 echo나 print_r 등의 출력 함수를 사용하면, response에 담겨서 나가게 되는데, 위와 같이 img 처럼 특정 확장자의 파일을 response 하고싶으면, header 에 타입을 꼭 지정해 줘야한다.