busboyでパースした画像が開けない時の対応

公開日:2021/8/21更新日:2023/1/21

Netlify Functionsを使った問い合わせフォームを作る時に、FormData(multipart/form-data)でpost送信されたデータをパースするためにbusboyを使ったのですが、画像のパースが上手くいかず、開けない画像として扱われてしまいました

結局、クライアント側でpost送信する前に、画像をBase64エンコードすることで対応できたので、参考までに。

ファイルを変換するための処理が1つ増えますし、Base64エンコードすることでデータも肥大化してしまうのですが、ほとんどの場合で使える回避策かと思います。

例として、一連のコードを記述します。Vuetifyでのコードですが、適宜変換して読み進めていただければと思います。

Inputファイル

ファイルの選択時にselectFileイベントが発火するようにします。

<v-file-input
  name="file"
  label="添付ファイル"
  accept="image/*"
  @change="selectFile"
/>

ファイル選択イベント

selectFileイベントを定義します。

selectFile(file?: File) {
  if (file) {
    const reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = () => {
      if (typeof reader.result === "string") {
        this.formFields.attachment = {
          name: file.name,
          url: reader.result // reader.result = Base64エンコードされた画像データ
        };
      }
    };
  }
}

データを送信

最後にデータを送信します。すべて文字列のため、FormDataを使う必要はなく、特別な設定なしでそのまま送信してOKです。

axios
  .post("/api/contact-form", this.formFields)
  .then(() => {
    // 成功時の処理
  })
  .catch(error => {
    // 失敗時の処理
  });

補足

Netlifyの参考記事では、画像ではなくsvgファイルの添付が例になっており🤔、svgファイルの添付は上手くいったのですが、画像ファイルを添付できない理由がわからず、最終的にBase64で対応することにしました。

当初、Nodemailerでの送り方が悪いのかなと思ったのですが、画像データがそもそもおかしく、色々と試したものの、根本的な解決には至りませんでした。