LoginSignup
2
2

More than 5 years have passed since last update.

Azure Functions + node.js で Multipart/Post ファイルアップロード

Posted at

流行りの「日本のITエンジニアが書いた」「やってみた」「個人メモ」な投稿です。

image.png

こういうファイルアップロード用のフォームで、ファイルのアップロードを受け付ける機能を、Azure Functions + node.js で作ります。
このような機能の場合、multipart に対応しないといけないのがポイントです。

今回は multipart 対応に、multer という npm パッケージを使います。

とりあえず Azure ポータルで、Functions App を node.js で作り、次のように package.json ファイルを配置します。

package.json

{
  "name": "uploader",
  "version": "0.0.0",
  "private": true,
  "scripts": {
    "start": "node ./bin/www"
  },
  "dependencies": {
    "memory-streams": "^0.1.3",
    "multer": "^1.4.0"
  }
}

次に index.js を次のように書き換えます。

index.js

const fs = require('fs');
const path = require('path');
const multer = require('multer');
const streams = require('memory-streams');
const upload = multer({ storage: multer.memoryStorage() });

module.exports = function (context, req) {
    context.log('JavaScript HTTP trigger function processed a request.');
    const stream = new streams.ReadableStream(req.body); 
    for (const key in req) {
        if (req.hasOwnProperty(key)) {
            stream[key] = req[key];
        }
    }
    context.stream = stream;

    upload.any()(stream, null, (err) => {
        const f = context.stream.files[0]
        const p = path.join(__dirname, `./${f.originalname}`);
        fs.writeFileSync(p, f.buffer);
        context.res = { body: `Upload ${f.originalname} done.` };
        context.done();
    });
};

package.json

{
  "name": "uploader",
  "version": "0.0.0",
  "private": true,
  "scripts": {
    "start": "node ./bin/www"
  },
  "dependencies": {
    "memory-streams": "^0.1.3",
    "multer": "^1.4.0"
  }
}

次に Azure Portal のコンソールで npm install を実行します。

image.png

サーバー側はこれで終わりなんで、「関数のURLを取得」しておきます。あ、メニューの 統合 の方で、「POST を許可する」のと「承認レベルを anonymous にする」のを忘れずに。

image.png

次にクライアント側をテキトーに作ります。

を参考にさせていただいて、 index.html を次のように記述してフォームを作ります。

<!DOCTYPE html>
<html>
<body>
  <form method="post" action="https://xxxx.azurewebsites.net/api/HttpTriggerJS1" enctype="multipart/form-data">
    <input type="file" name="example1">
    <input type="submit" value="SEND">
  </form>
</body>
</html>

action に指定するURLはさっきコピった Azure Function の関数のURLです。
できたら node server01.js で Webサーバを起動し、 ttp://localhost:8001 でフォームを表示します。
適当なファイルを選択して「SEND」ボタンを押せば、ファイルがアップロードされるはずです。
アップロードが完了するとページ遷移して「Upload xxxx.xxx done.」という表示になります。

さて、ファイルが実際にどこにアップロードされたかというと、Azure Functions が配置されたディレクトリに保存されています。

試しにフォームから input.png というファイルをアップロードしたあとで、Azure ポータルの方でコンソールを開いて ls -l を実行すると、下図のように input.png が存在していることがわかります、ファイルサイズもなんかそれっぽいので成功しているのでしょう。

image.png

未確認なこと

  • ちゃんとマルチパートな送信データを処理できるよね? → フォームで送ったらパートが一つだけだったので未確認。
  • 大きなファイルサイズ耐えられる? → ダメかも。5MB程度のファイルをアップロードしたら 502 エラーになりますた。どこまで耐えられてどうしたら上限引き上げられるのかは未調査。
2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2