ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • form에 이미지 파일 전송하기
    JavaScript 2023. 9. 21. 09:28

    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 에 타입을 꼭 지정해 줘야한다.

Designed by Tistory.