花粉症に悩まされる時期がまだまだ続いておりますが、強力な薬を服用することで凌いでます。
さて、今回はnuxt3でファイルアップロードを実装する方法を見ていきます。nodejsのexpressアプリケーションでは、multerやformidableといった素晴らしいライブラリを使って簡単にアップロード処理を実装することができます。nuxt3(h3)でmulterやformidableのライブラリを使うこともできるのですが、外部ライブラリを使わずとも標準機能で簡単にファイルアップロードを実装することができるようになっています。今回はその方法を見ていきます。
環境
- macOS Catalina (intel cpu)
- nuxt 3.4.1
- Node.js 18.15.0
サンプル
早速サンプルを見ていきます。
app.vue
fetchでformデータを処理するにはFormDataを使います。今回は、textとfileの2種類のデータをPOSTするサンプルとしています。
<script setup lang="ts">
const files = ref<FileList>();
const title = ref("");
const uploadData = ref();
function changeFiles(event: Event) {
const result = event!.target as HTMLInputElement;
files.value = result.files!;
}
async function upload() {
const formData = new FormData();
formData.append("title", title.value);
if (files.value) {
for (const item of files.value!) {
formData.append("files", item, encodeURIComponent(item.name)); // 日本語ファイル名はエンコード
}
}
await useFetch("/api/upload", {
method: "POST",
body: formData,
}).then((result) => {
uploadData.value = result.data;
});
}
</script>
<template>
<div>
<h2>File Uploads</h2>
<form @submit.prevent="upload">
<div>Text field title: <input type="text" name="title" /></div>
<div>
File: <input type="file" name="files" @change="changeFiles" multiple />
</div>
<input type="submit" value="アップロード" />
</form>
{{ uploadData }}
</div>
</template>
server/api/upload.post.ts
readMultipartFormDataという関数でbodyをパースします。この関数は、nuxt3の内部で使われているh3というフレームワークが提供している関数です。関数の引数にeventオブジェクトを渡すとパースした結果が返ります。
export default defineEventHandler(async (event) => {
const files = await readMultipartFormData(event);
if (!files || files.length === 0) {
throw createError({
statusCode: 400,
statusMessage: "No files were uploaded",
});
}
const uploaded = files.map((item) => ({
contentType: item.type,
filename: decodeURIComponent(item.filename!), // エンコードしているのでデコード
name: item.name,
size: item.data.length,
}));
return { uploaded };
});
早速実行してみましょう。3つの日本語ファイル名を含む画像ファイルを送信してみます。


リクエストした結果を返せていることが分かります。
まとめ
nuxt3では、標準でファイルアップロードを実装するための関数があります。multerやformidableのようにファイルデータをディスクに保存したりといった他の付加機能はないので、そこは自分で実装する必要があります。
参考リンク
- https://github.com/unjs/h3
- https://github.com/unjs/h3/blob/main/src/utils/internal/multipart.ts
- https://github.com/node-formidable/formidable
- https://github.com/expressjs/multer


コメント