시나리오
<!-- routes/img/+page.svelte -->
<script>
let file;
function handleFileChange(event) {
const selectedFile = event.target.files[0];
if (selectedFile) {
file = selectedFile;
}
}
async function uploadImage() {
// 1. createURLComponent 사용
// OR 2. sessionStorage에 저장
// OR 3. store에 저장
goto("img/result");
}
</script>
<input type="file" accept="image/*" onchange={handleFileChange} />
<button onclick={uploadImage}>Upload</button>
/img에서 input 태그를 이용해 이미지 파일을 업로드한다. 이미지가 선택되면 handleFileChange를 통해 file 변수가 업데이트된다.
Upload 버튼을 누르면 /img/result로 이동해 사진을 띄운다.
1. URL로 전달
API로부터 전달받은 이미지를 URL로 변환해 /result?image=...로 전달한다. 그럼 API는 URL의 image를 읽어 처리한다.
async function uploadImage() {
// 이미지를 URL로 변환
const url = URL.createObjectURL(file);
goto(`/img/result?image=${encodeURIComponent(url)}`);
}
- createObjectURL을 통해 파일을 브라우저 메모리에 저장하고, 주소 참조값을 받는다.
- 문자열(주소)은 encodeURIComponent를 통해 안전한 URL 형식으로 바뀐다.
- goto를 통해 /result?image=로 이동한다.
<!-- routes/img/result/+page.svelte -->
<script>
import { browser } from "$app/environment";
let processedImage = "";
if (browser) {
// URL 가져오기
const urlParams = new URLSearchParams(window.location.search);
// 이미지를 변수에 저장
let processedImageUrl = urlParams.get("image");
processedImage = decodeURIComponent(processedImageUrl);
}
</script>
{#if processedImage}
<img src={processedImage} alt="" />
{/if}
이 방식은 URL에 불필요한 정보가 노출된다.
2. sessionStorage 사용
sessionStorage를 사용하면 새로고침해도 문제없이 이미지를 보여준다.
// routes/img/+page.svelte
import { goto } from "$app/navigation";
let file;
async function uploadImage() {
// base64로 변환
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => {
// 이미지 저장
sessionStorage.setItem("image", file);
goto("/img/result");
}
}
- 이미지를 Base64로 인코딩해 setItem으로 sessionStorage에 저장한다.
- /img/result로 이동해 파일을 읽어온다.
<!-- routes/img/result/+page.svelte -->
<script>
import { onMount } from "svelte";
let processedImage = "";
onMount(() => {
processedImage = sessionStorage.getItem("image");
});
</script>
- 브라우저를 새로고침해도 문제 없이 작동한다.
- URL에 정보를 노출하지 않는다.
- Base64 인코딩 과정에서 파일 용량이 커진다.
3. Store 사용
svelte/store는 변경 가능한 state를 선언하는 writable 함수를 제공한다.
// src/lib/stores.js
import { writable } from "svelte/store";
export const imageStore = writable(null);
이미지를 imageStore에 저장한 뒤, 다른 페이지에서 불러올 수 있다.
// routes/img/+page.svelte
async function uploadImage() {
// base64로 이미지 변환
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => {
// 이미지 저장
imageStore.set(reader.result);
goto("/img/result");
};
}
<!-- routes/img/result/+page.svelte -->
<script>
import { imageStore } from "$lib/stores.js";
let processedImage;
imageStore.subscribe((value) => (processedImage = value));
</script>
set으로 이미지를 저장하고, subscribe로 불러온다.
- URL에 정보를 노출하지 않는다.
- 새로고침하면 오류가 발생한다.
새로고침이 가능하도록 하기 위해 2번 방법과 3번 방법을 함께 사용할 수도 있다.
이 외에도 서버에 이미지를 저장해 가져오는 등 방법이 있다.