presignedUrl 를 통해 자체 S3 버킷에 이미지를 업로드
insert 할 때, requestSubmitFn을 통해 선택된 파일들을 s3 presigned url 발급 받아서 업로드하는 예시입니다.
requestSubmitFn: |
try {
const response = await fetch("generate-presigned-url", {
method: 'GET',
mode: 'cors'
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const result = await response.json();
const presignedData = result[0];
const url = presignedData.url;
const fields = presignedData.fields;
// 업로드할 파일
const file = document.querySelector('#thumbnail').files[0];
console.log('Uploading file:', file);
const formData = new FormData();
formData.append('key', fields.key);
formData.append('acl', fields.acl);
formData.append('bucket', fields.bucket);
formData.append('X-Amz-Algorithm', fields['X-Amz-Algorithm']);
formData.append('X-Amz-Credential', fields['X-Amz-Credential']);
formData.append('X-Amz-Date', fields['X-Amz-Date']);
formData.append('Policy', fields.Policy);
formData.append('X-Amz-Signature', fields['X-Amz-Signature']);
formData.append('Content-Type', file.type); // 파일의 MIME 타입
formData.append('file', file);
const uploadResponse = await fetch(url, {
method: 'POST',
body: formData
});
if (uploadResponse.ok) {
console.log('File uploaded successfully');
} else {
console.error('File upload failed', uploadResponse.statusText);
}
} catch (error) {
console.error('Failed to fetch presigned URL:', error);
}
위 코드는 JavaScript를 사용하여 파일을 업로드하는 비동기 요청 함수입니다. 주로 AWS S3와 같은 스토리지 서비스에 파일을 업로드할 때 활용됩니다. 다음은 코드의 주요 흐름과 작동 방식을 설명합니다:
1. Presigned URL 가져오기
const response = await fetch("generate-presigned-url", {
method: 'GET',
mode: 'cors'
});
generate-presigned-url
은 presigned URL을 생성해주는 API 엔드포인트입니다.fetch
를 사용해 GET 요청을 보냅니다.- 서버가 presigned URL과 필요한 필드들을 응답으로 제공합니다.
2. Presigned URL 유효성 검사 및 데이터 추출
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const result = await response.json();
const presignedData = result[0];
const url = presignedData.url;
const fields = presignedData.fields;
- 응답이 성공(
200 OK
)인지 확인하고, JSON 데이터를 추출합니다. presignedData
는 파일 업로드에 필요한 URL 및 필드 데이터를 포함합니다:url
: 파일을 업로드할 대상 URL.fields
: 업로드 요청 시 필요한 필드 데이터(예: 인증 정보, 정책 등).
3. 파일 선택 및 준비
const file = document.querySelector('#thumbnail').files[0];
console.log('Uploading file:', file);
- 사용자가 업로드할 파일을 선택해야 합니다.
#thumbnail
는 HTML<input type="file" id="thumb">
와 연결된 파일 입력 요소입니다. (params에id: thumbnail
)- 선택된 파일 객체(
file
)를 준비합니다.
4. 폼 데이터 구성
const formData = new FormData();
formData.append('key', fields.key);
formData.append('acl', fields.acl);
formData.append('bucket', fields.bucket);
formData.append('X-Amz-Algorithm', fields['X-Amz-Algorithm']);
formData.append('X-Amz-Credential', fields['X-Amz-Credential']);
formData.append('X-Amz-Date', fields['X-Amz-Date']);
formData.append('Policy', fields.Policy);
formData.append('X-Amz-Signature', fields['X-Amz-Signature']);
formData.append('Content-Type', file.type); // 파일의 MIME 타입
formData.append('file', file);
FormData
객체를 생성하고 필요한 데이터를 추가합니다.fields
에 포함된 인증 및 정책 정보를 폼 데이터에 추가합니다.- 업로드할 파일(
file
)도 포함합니다.
5. 파일 업로드
const uploadResponse = await fetch(url, {
method: 'POST',
body: formData
});
- presigned URL로
POST
요청을 보내 파일을 업로드합니다. - 요청 본문에
formData
를 포함합니다.
6. 응답 처리
if (uploadResponse.ok) {
console.log('File uploaded successfully');
} else {
console.error('File upload failed', uploadResponse.statusText);
}
- 업로드 요청 결과를 확인합니다.
- 성공 시 "File uploaded successfully"를 로그로 출력합니다.
- 실패 시 에러 메시지를 출력합니다.
7. 에러 처리
} catch (error) {
console.error('Failed to fetch presigned URL:', error);
}
- presigned URL 요청 또는 업로드 중 에러가 발생할 경우 적절히 처리합니다.
요약
이 코드는 다음과 같은 상황에서 유용합니다:
- Presigned URL 기반 파일 업로드: AWS S3와 같은 스토리지 서비스에 안전하게 파일을 업로드하기 위해 사용.
- 보안 강화: 파일 업로드에 필요한 인증 데이터를 포함한 presigned URL을 사전에 생성해 서버 측에서 관리.
- 사용자 경험 개선: 비동기로 처리되어 사용자 인터페이스가 멈추지 않음.
추가적으로, #thumbnail
에 올바른 파일 입력 요소를 연결하고, presigned URL을 제공하는 서버 API가 잘 동작하는지 확인해야 합니다.
관련하여 도움이 필요하시다면 문의해주세요.
감사합니다.