- PNG: 고품질 이미지, 투명도 지원.
- JPG: 사진에 적합, 파일 크기 작음, 손실 압축.
- GIF: 애니메이션 지원, 색상 제한.
파일업로드
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Image Upload</title>
</head>
<body>
<h2>Upload an Image</h2>
<form action="/upload" method="POST" enctype="multipart/form-data">
<input type="file" name="image" accept="image/*">
<button type="submit">Upload</button>
</form>
</body>
</html>
- <input type="file">: 파일 업로드를 위한 입력 필드입니다.
- name="image": 서버로 전송될 때의 파라미터 이름입니다.
- accept="image/*": 이미지 파일만 선택하도록 제한합니다.
- enctype="multipart/form-data": 파일 데이터를 포함해 폼을 제출하려면 반드시 설정해야 합니다
이미지프리뷰
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Image Upload with Preview</title>
</head>
<body>
<h2>Upload and Preview an Image</h2>
<form>
<input type="file" id="imageInput" accept="image/*">
<div id="preview">
<p>No image uploaded yet.</p>
</div>
</form>
<script>
const imageInput = document.getElementById('imageInput');
const preview = document.getElementById('preview');
imageInput.addEventListener('change', function(event) {
const file = event.target.files[0];
if (file) {
const reader = new FileReader();
reader.onload = function(e) {
preview.innerHTML = `<img src="${e.target.result}" alt="Uploaded Image" style="max-width: 100%; max-height: 300px;">`;
};
reader.readAsDataURL(file);
} else {
preview.innerHTML = '<p>No image uploaded yet.</p>';
}
});
</script>
</body>
</html>
다운로드
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Download with JavaScript</title>
</head>
<body>
<h2>Download Image with JavaScript</h2>
<button id="downloadButton">Download Image</button>
<script>
document.getElementById('downloadButton').addEventListener('click', function () {
const link = document.createElement('a');
link.href = '/download/example.jpg'; // 서버 파일 URL
link.download = 'example.jpg'; // 다운로드 파일 이름
link.click();
});
</script>
</body>
</html>
Chrome, Samsung Browser
const blob = new Blob(["hello"], { type: "text/plain" });
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = "test.txt";
a.click();
Safari
window.open(blobUrl, "_blank");
위 방법도 완전하지는 않음
Content-Disposition: attachment
Content-Disposition: attachment
를 응답해더에서 붙여주는 방법이 가장 안정적
web서버와 was가 분리되어 있다면 특정 웹서버는 설정을 통해 web의 파일을 다운로드할 수 있다.
더보기
[Browser]
│ 1️⃣ 다운로드 요청
▼
[Spring WAS]
│ - 인증 / 권한 체크
│ - Content-Disposition 결정
│ - X-Accel-Redirect 헤더 응답
▼
[Nginx]
│ 2️⃣ 내부 경로 매핑
│ 3️⃣ 실제 파일 전송
▼
[File System (/data/files)]
Nginx 설정 (파일 전송자)
예: 실제 파일 위치
/data/files/report.pdf
location /internal-files/ {
internal; # 외부 직접 접근 차단
alias /data/files/; # 실제 파일 디렉토리
}
Spring Boot 컨트롤러 (허가·헤더 결정자)
@GetMapping("/files/download/{filename}")
public ResponseEntity<Void> download(
@PathVariable String filename,
Principal principal) {
// 1️⃣ 권한 체크
if (!hasPermission(principal, filename)) {
return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
}
// 2️⃣ 파일명 인코딩 (한글 필수)
String encoded = URLEncoder.encode(filename, StandardCharsets.UTF_8)
.replaceAll("\\+", "%20");
String contentDisposition =
"attachment; filename*=UTF-8''" + encoded;
// 3️⃣ Nginx에게 파일 전송 위임
return ResponseEntity.ok()
.header("X-Accel-Redirect", "/internal-files/" + filename)
.header(HttpHeaders.CONTENT_DISPOSITION, contentDisposition)
.build();
}
Jquery 이미지 서버전송
/**
* BASE64를 BLOB데이터로 변환
* @param base64
* @param contentType
* @returns {Blob}
*/
function convertBlobToJson(base64, contentType) {
const byteCharacteres = atob(base64);
const byteArrays = [];
for(let offset = 0; offset < byteCharacteres.length; offset += 512) {
const slice = byteCharacteres.slice(offset, offset+512);
const byteNumbers = new Array(slice.length);
for(let i = 0; i<slice.length ; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}
const byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}
return new Blob(byteArrays, {type : contentType});
}
const imgBlob = convertBlobToJson(base64img, "image/jpg");
const jpegData = new File([imgBlob], "img.jpg", {type : "image/jpg"});
const formData = new FormData();
formData.append("jpegData", jpegData);
$.ajax({
url: "/upload", // 파일을 전송할 서버의 URL (Spring Boot, Express 등)
type: "POST",
data: formData,
contentType: false, // jQuery가 Content-Type을 자동으로 설정하지 않도록 설정
processData: false, // jQuery가 데이터를 처리하지 않도록 설정
success: function (response) {
$("#response").html("<p>Upload successful! " + response.message + "</p>");
},
error: function (xhr, status, error) {
$("#response").html("<p>Error: " + error + "</p>");
}
});'WEB개발 > JS&HTML' 카테고리의 다른 글
| Typescript (1) | 2023.12.18 |
|---|---|
| [JS] 자바스크립트 템플릿 리터럴 백틱(``), 달러(${ }) (0) | 2023.10.25 |
| [JS] 모듈(module, import, export) (0) | 2023.10.25 |
| [JS] Deferred (0) | 2023.07.22 |
| [JS] Async, Await, Fetch, PromiseAll (0) | 2023.03.06 |