ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [react] s3에 여러 이미지 파일 업로드하기
    react 2023. 4. 15. 23:56
    반응형

    이미지나 동영상과 같은 파일을 선택해서 s3버킷에 저장하는 과정을 정리 하는 글이다.

    크게 3가지 과정으로 정리를 하려고한다.

     

    1. 파일 핸들링

    2. 버킷생성

    3. 버킷에 업로드

     

    1.파일 핸들링은 input tag를 통해서 파일을 선택하고 업로드할 파일을 미리볼수 있게하는 과정을 이야기한다.

    2.버킷생성은 aws 에서 버킷을 생성하는 과정이다.

    3.버킷에 업로드는 선택한 파일을 버킷에 저장하고 저장위치를 보여주는 과정을 이야기 한다. 보통은 저장한 위치를 db에 저장할수있도록 업로드 성공이후에 저장위치를 서버(백엔드)에 보내준다.

     

    input tag에서 특정형식의 파일타입만 받는다거나 여러파일을 받는다거나 하는 세부적인 상황, aws에서 버킷을 생성하는 방법, file객체 에 대한 내용은 생략할 예정이고 여러파일을 업로드 하는 대략의 과정정도로 생각하면 좋다.

     

    1.  파일 핸들링

    import React, { useState } from "react";
    import UploadPreview from "@/components/UploadPreview";
    
    interface FileInfoType {
    	url: string;
    	image: boolean;
    	video: boolean;
    	file: File;
    }
    
    const FilePage = () => {
      const [files, setFiles] = useState<FileInfoType[]>([]);
    
      const onChangeFile = (e: React.ChangeEvent<HTMLInputElement>) => {
        const list: FileInfoType[] = [];
        const fileList = e.target.files;
    
        if (fileList) {
          for (let i = 0; i < fileList.length; i++) {
            list.push({
              url: URL.createObjectURL(fileList[i]),
              image: fileList[i].type.includes('image'),
              video: fileList[i].type.includes('video'),
              file: fileList[i],
            })
          }
        }
        setFiles(list);
      }
    
      return (
    
        <div>
          <input type="file" onChange={onChangeFile} multiple />
          <UploadPreview files={files} />
        </div>
      )
    };
    
    export default FilePage;

    onChangeFile 함수는 input 태그를 통해서 받은 파일을 핸들링 하는 함수이다.

    미리보기시 파일형식에 맞게 보여주기 위해서 interface FileInfoType 형태로 저장했다.

    url: 파일정보를 미리보기 할수있도록 변환된값이다.
    image,video : 미리보기시 파일의 유형을 참고 하기 위해서 만든 속성이다.

    file : 이후 저장버튼 클릭시 파일정보를 업로드 하기위해 저장한 객체이다.

     

    2. 버킷 생성

    버킷의 기본적인 생성 이후에 유의사항만 알아보자.

    1. 퍼블릭 엑세스 차단 비활성화 : 쓰기권한이 불특정 다수로 부터 쓰여지기 때문에 필요한 부분이다.

    2. 버킷 정책 작성 : 버킷의 객체에 대한 작업을 수행할 수 있는 역할 및 사용자를 구체적으로 지정할 수 있습니다. 상황에 맞게 필요한 동작을 지정해주면 된다.

    3. cors 구성편집 : 업로드가능한 주소목록 관리 및 요청메서드 관리를 해줄수 있는 부분이다. cors 에러가 난다면 이부분을 편집해주면 된다.(Access to XMLHttpRequest at 'https://ap-northe...s.com/upload/problem_5.png' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.)

    좌측부터 1,2,3 버킷의 권한 설정부 이다.

    3. 버킷에 업로드

    import React, { useState } from "react";
    import UploadPreview from "@/components/UploadPreview";
    import AWS from 'aws-sdk';
    
    const FilePage = () => {
      AWS.config.update({
        accessKeyId: process.env.NEXT_PUBLIC_AWS_ACCESS_KEY,
        secretAccessKey: process.env.NEXT_PUBLIC_AWS_SECRET_ACCESS_KEY,
        region: process.env.NEXT_PUBLIC_REGION
      });
      const s3 = new AWS.S3();
    
      const [files, setFiles] = useState<FileInfoType[]>([]);
    
      const onChangeFile = (e: React.ChangeEvent<HTMLInputElement>) => {
        ...
        setFiles(list);
      }
    
      const uploadFile = async () => {
        if (files.length === 0) return;
    
        const uploadPromise = files.map(({ file }) => {
          const params = {
            Bucket: process.env.NEXT_PUBLIC_AWS_BUCKET as string,
            Key: `${Date.now()}.${file.name}`,
            Body: file
          };
          return s3.upload(params).promise();
        })
    
        const results = await Promise.all(uploadPromise);
        const locations = results.map(result => result.Location);
        // 백엔드로 저장하는 요청 로케이션과 같이 보내주기
      }
    
      return (
    
        <div>
          <input type="file" onChange={onChangeFile} multiple />
          <UploadPreview files={files} />
          <button onClick={uploadFile}>저장</button>
        </div>
      )
    };
    
    export default FilePage;

    - aws.config.update({...}) 를 통해서 aws 인증정보와 지역정보설정

    : aws에서 엑세스키와 시크릿키를 만들고 env 파일에 넣어두었다. aws > 보안 자격 증명 > 액세스 키 > 생성 

    : iam 계정에서 꼭해야하는건 아니고 루트계정에서 해도 되긴하는데 iam 계정에서 키생성을 권하고 있다.

    - uploadPromise 만들기 

    :s3.upload(params).promise() > promise() 메서드는 aws request 객체에서 사용할수 메서드로 Promise 객체를 반환하여 유연한 코드작성을 도와준다.

    :promise.all()을 통해서 모든이미지가 업로드 성공후에 서버에 전달 할수 있게 하기위해 promise 객체의 배열 생성 과정이다.

     

     

     

    업로드 결과 예시

     

     

    'react' 카테고리의 다른 글

    [error] nextjs api routes vercel 배포시 504에러  (0) 2023.04.28
    [error] nextjs Image 관련  (0) 2023.04.16
    [Nextjs] dynamic import 에 대하여  (0) 2023.04.06
    [react]리액트 되돌아보기 2  (0) 2022.11.08
    [react] 리액트 되돌아보기  (0) 2022.10.17
Designed by Tistory.