SvelteKitでファイルアップロード機能を実装する
Sveltekit を用いたプロジェクトでのファイルアップロード機能を実装します。開発中の備忘録です。
作るもの
ローカル PC に存在するファイルをサーバー上の任意のフォルダにアップロードする機能です。
またアップロード後にそのファイルなどを用いた処理を行えるようにします。
環境
事前に SvelteKit での環境は作ってある前提で話を進めます。
-
svelte: ^5.0.0 -
sveltejs/kit: ^2.9.0
コード
アップロードフォーム
src/routes/+page.svelteを編集します。特に変哲もないファイルアップロードのためのHTMLフォームですね。
multipart/form-dataでファイル送信の準備をしておきます。
<form method="post" enctype="multipart/form-data">
<input type="file" name="file" />
<button>Upload</button>
</form>
アップロード処理
src/routes/+page.server.jsに以下のコードを記述します。
+page.server.jsファイルはactionsをエクスポートするためです。
import { writeFile } from 'fs/promises';
import { Buffer } from 'buffer';
import path from 'path';
/** @type {import('./$types').Actions} */
export const actions = {
default: async ({ request }) => {
try{
const formData = await request.formData();
const file = formData.get('file');
const fileName = `${randomUUID()}${path.extname(file.name)}`;
const filePath = `./static/uploads/${fileName}`;
await writeFile(filePath, Buffer.from(await file.arrayBuffer()));
return { success: true, fileName: fileName };
} catch (e){
// エラー時の処理を記述
return { success: false }
}
}
};
actionオブジェクトにはdefaultプロパティを置き、フォームが送信されたときに実行される非同期関数を記述します。
formData()でアップロードされたファイル情報を準備し、fileにローカルからアップロードされたファイル情報を格納します。
.get('file')の'file'はフロントエンド側のフォーム入力部分の名前です。
ファイルネームは適当に決めちゃってください。path.extnameでアップロードされたファイルの拡張子を取得しています。
サーバーへのアップロードにはwriteFileを用いて行います。writeFileではファイル情報をBuffer等で指定することが求められているのでそれに従います。
アップロードに成功したら、成功した旨を伝える情報とファイル名を返します。これでファイルのアップロード自体は終了しました。
成功を受け取る
成功したことをフロントエンド側で受け取ります。
フロントエンドで情報を受け取ることでページ遷移等なしで、次の処理(アップロードファイルの表示とか?)を行うことができます。
src/routes/+page.svelteに以下の記述を追加します。
<script>
export let form;
</script>
<!-- さっきのフォームのコード -->
{#if form?.success}
<!-- ここに成功時の処理を記述 -->
<p>ファイル名:{form.fileName}</p>
{:else}
<!-- ここに失敗時の処理を記述 -->
<p>エラーです!</p>
{/if}
( .svelteのシンタックスハイライト対応してなくて悲しい )
export let formで+page.server.jsでの返り値を取得します。
下部で返り値の情報により条件分岐させ、その後の処理を指定することができます。
おーわり!
Discussion