TypeScript (と VSCodeのREST Client) でmultipart/form-dataのデータを送受信

7355 ワード

はじめに

TypeScriptでファイルをPOSTして、それを受け取る方法がよく分かってなかったので、調べながら実装した。HTTPでmultipart/form-dataを送るときのboundaryについても少し理解が深まったので、記録。

コード

バックエンドのコードとフロントエンドのコードとテスト用のVSCodeのREST Clientのコードを整理。

multer @ バックエンド

こんな感じで受け取って、処理する。
受け取ったファイルはメモリに保存したかったので、storagemulter.memoryStorageを指定してる。destにパスを指定したらファイルとして保存されるみたい。

import express from 'express';
import multer from 'multer';

const app = express()

const upload = multer({ storage: multer.memoryStorage() })
// const upload = multer({ dest: 'uploads/' })

app.post('/api/upload', upload.single('file'), (req: express.Request, res: express.Response, next: express.NextFunction) => {
  console.log(req.file)
})

axios @ フロントエンド

フロントエンドでaxiosを使うなら、こんな感じ。fileはBlobでも送れた。

const file = fs.createReadStream('./audio.wav');
const data = new formData();
data.append('file', file);
axios.post('/api/upload', data, {
    headers: {
        'content-type': 'multipart/form-data',
    }
})

REST Client @ VSCode

こんな感じでファイルをmultipart/form-dataとしてpostできる。バックエンド側でupload.single('file')として受け取れるように、name="file"としてデータを送ってる。

.http
### upload
POST http://localhost:8000/api/upload
Content-Type: multipart/form-data; boundary=MyBoundary

--MyBoundary
Content-Disposition: form-data; name="file"; filename="audio.wav"
Content-Type: audio/wav

< ./audio.wav
--MyBoundary--

おわりに

boundaryよくわからんまま使おうとしたけど、凡ミスでうまく動かずまじめに調べた。HTTPのブラックボックスやった部分を垣間見れてよかった。
あとやっぱり、REST Clientすごく便利。

参考

ここら辺が参考になった。ありがたや。

Multer @ バックエンド

expressjs/multer: Node.js middleware for handling multipart/form-data.

これを使ったら、受け取ったファイルのハンドリングをいい感じにできる。

axios x form-data @ フロントエンド

axios/axios: Promise based HTTP client for the browser and node.js
Node.jsからExpressへファイルのアップロードを処理する方法 | www.twilio.com

axiosとform-data使ったら、簡単に送れる。

REST Client @ VSCode

Huachao/vscode-restclient: REST Client Extension for Visual Studio Code

multipart/form-dataのpostの仕方も書かれてる。

multipart/form-data @ HTTP

Content-Type - HTTP | MDN
【HTTP】multipart/form-data の boundary って何ぞや? - Qiita

boundaryとかがよくわからなかったので調べた。ここらに書いてあった。ふむふむ。