티스토리 뷰

반응형

React에서 formData를 사용하여 파일을 전송하다보면 body에 다른값들을 같이 전송해야하는데 잘 되지않는 경우가 있더라구요. 이미지를 base64 형식으로 서버에 전송하는 방법입니다.
서버에서 전달 받은 이미지를 decode 및 저장하는 코드는 https://seung-min.tistory.com/38 를 확인해주세요.  

 

[node.js] base 64 이미지 decode 및 저장 방법

웹에서 보낸 base64 이미지 파일을 받아서 decode 및 저장하는 방법입니다. react 에서 base64 형태로 이미지 업로드 방법은 https://seung-min.tistory.com/37 여기에 있습니다. [React] base64로 여러 장의 이..

seung-min.tistory.com

 

 

 

 

    <div>
        <input
            type="file"
            multiple
            style={{ display: "none" }}
            id="photo_file"
            name="photo_file"
            accept=".jpg"
            onChange={handleImageUpload}
        />
        <label class="btn btn-secondary border-0 bg_grey" for="photo_file">
            사진 추가
        </label>
    </div>

 input 태그에 accept 옵션을 통해 확장자를 제안할 수 있습니다. 여러개의 확장자 사용시 ,로 구별해서 작성하면 되고  type='file" 경우에만 사용 가능합니다. 

multiple 옵션을 줘서 한번에 여러 파일을 선택 할 수 있습니다.

onChange 함수를 사용하여 데이터를 처리해줍니다.

    
    
    const [sendImgs, setSendImgs] = useState([]);
    
    const handleImageUpload = (e) => {
        setBtnRefreshUser((val) => !val);
        setInferResult([]);
        const fileArr = e.target.files;

        let fileURLs = [];

        let file;
        let maxFile = 50;
        let filesLength = fileArr.length > maxFile ? maxFile : fileArr.length;

        if (fileArr.length > maxFile) alert(`한번에 업로드 가능한 사진은 최대 ${maxFile}장 까지 입니다.`);

        for (let i = 0; i < filesLength; i++) {
            file = fileArr[i];

            if (file.type !== "image/jpeg" && file.type !== "image/jpg") {
                setSendImgs([]);
                alert(`JPG 사진 파일만 가능합니다.`);
                break;
            } else {
                let reader = new FileReader();

                reader.onload = () => {
                    fileURLs[i] = reader.result;

                    setSendImgs([...fileURLs]);
                };
                reader.readAsDataURL(file);
            }
        }
    };

e.target.files에서 넘어온 이미지들을 배열에 저장 합니다. 그 후 한번에 업로드 하려는 이미지의 최대 개수, type 등을 한번 더 검증해줍니다. 통과된 파일들은 FileReader를 사용하여 이미지 파일을 읽고 전송하려는 스테이트에 넣어줍니다.

 

 setSendImgs([...fileURLs]);

위의 코드에서 ...은 전개 연산자 입니다.
es6의 문법으로 es5의 배열 리터럴 함수 conat을 대체 해 주는 연산자입니다. 

전개 연산자를 사용하지 않을 경우, 그냥 배열을 넣을 경우 객체로 값이 들어가게 됩니다. 배열에 있는 값이 필요한 경우 배열의 값을 하나씩 다 불러와서 사용하거나, 배열 리터럴함수, 전개 연산자를 사용해야합니다.

 

 *accept에서 jpg만 제한을 뒀지만, 모든 파일을 선택하게 변경 할 수있어서 Server에 보내기전에 파일 타입에 대한 검증을 한번 더 진행해줘야합니다.

 

이제 전송 버튼을 누를 경우  axios를 사용하여 서버로 데이터를 보내주면 됩니다.

    const onClickHandler = () => {
        if (sendImages) {
            axios
                .post(
                    `${process.env.REACT_APP_API_SERVER_HOST}/api/경로 작성`,
                    {
                        sendImages,
                    },
                    header
                )
                .then((res) => {
                    if (res.data) {
                        alert(res.data.msg);
                    } else {
                        alert(res.data.msg);
                    }
                })
                .catch((err) => {
                    alert("전송 실패 : " + err);
                });
        }
    };

 

 

반응형
댓글
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG more
«   2024/07   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
글 보관함