如何在Node.js中上传图像和文件到Azure Blob

4

我有一个使用Angular作为前端的Node.js应用程序,需要上传文件和图像到Azure Blob。

我已创建容器并按照微软文档(https://learn.microsoft.com/en-us/azure/storage/blobs/storage-quickstart-blobs-nodejs)设置了环境,版本为v12。

我的函数可以创建并将文件上传到Azure Blob,但我无法弄清楚如何将客户端提交的文件上传到Azure Blob。以下是我的TypeScript Node.js代码:

  import * as formidable from 'formidable';
  import * as fs from 'fs';

  const { BlobServiceClient } = require('@azure/storage-blob');
  const uuidv1 = require('uuid/v1');
  const dotenv = require('dotenv');
  dotenv.config();

class BlobController {

    private AZURE_STORAGE_CONNECTION_STRING = process.env.CONSTRINGBlob;

   constructor(router) {
    router.post('/file', this.uploadFile.bind(this));
  }
 //----Get Lookup tables dynamically-----------//
 async uploadFile(req, res) {

    const blobServiceClient = await BlobServiceClient.fromConnectionString(this.AZURE_STORAGE_CONNECTION_STRING);
    // Create a unique name for the container
    //const containerName = 'quickstart' + uuidv1();
    const containerName = blobServiceClient.getContainerClient('mycontainer');
    console.log('\t', containerName.containerName);
    // Get a reference to a container
    const containerClient = await blobServiceClient.getContainerClient(containerName.containerName);
    let form = new formidable.IncomingForm();
    form.parse(req, async function (err, fields, files) {
        const blobName = 'test' + uuidv1() + files.file;
        // Get a block blob client
        const blockBlobClient = containerClient.getBlockBlobClient(blobName);
        console.log('\nUploading to Azure storage as blob:\n\t', blobName);
        // Upload data to the blob
        const data = 'Hello test';
        const uploadBlobResponse = await blockBlobClient.upload(data, data.length);
        console.log("Blob was uploaded successfully. requestId: ", uploadBlobResponse.requestId);
    });
 }
}

module.exports = BlobController

有谁能帮我解决如何使用Node.js上传发布到Azure Blob的文件吗?

3个回答

4
你离成功就差一步了:)。
请修改以下代码:
```html

```
form.parse(req, async function (err, fields, files) {
        const blobName = 'test' + uuidv1() + files.file;
        // Get a block blob client
        const blockBlobClient = containerClient.getBlockBlobClient(blobName);
        console.log('\nUploading to Azure storage as blob:\n\t', blobName);
        // Upload data to the blob
        const data = 'Hello test';
        const uploadBlobResponse = await blockBlobClient.upload(data, data.length);
        console.log("Blob was uploaded successfully. requestId: ", uploadBlobResponse.requestId);
    });

to:

  form.parse(req, async function (err, fields, files) {
    const file = files.file;
    const blobName = 'test' + uuidv1() + files.file;
    const contentType = file.type;
    const filePath = file.path;//This is where you get the file path.
    const blockBlobClient = containerClient.getBlockBlobClient(blobName);
    const uploadBlobResponse = await blockBlobClient.uploadFile(filePath);
  });

不理解为什么这是被接受的答案,问题明确说明文件和图像来自Angular客户端,因此您的解决方案是调用需要在Node.js服务器中使用filePath的函数!但是这个filePath不存在。 - VinKrish
@VinKrish - 当您使用form处理文件上传时,它会自动将上传的内容保存在临时文件中,并且file.path属性会给出该临时文件的完整路径。您不需要做任何特殊处理。请尝试此代码。希望对您有所帮助。 - Gaurav Mantri
我找到了一个更好的解决方案,将输入流传输到Azure上传函数中。 当我们的实现涉及容器和Lambda函数时,获取文件路径会变得棘手。 - VinKrish

1
//Here's my form.parse code I used to upload pictures.

form.parse(req, async (err: any, fields: any, files: any) => {        
    const file = files.file;
    const filePath = file.path;//This is where you get the file path. (this is the file itself)
    const blobName: string = slugify(file.name);

    const blockBlobClient = containerClient.getBlockBlobClient(blobName);

    const uploadBlobResponse = await blockBlobClient.uploadFile(filePath)
    console.log("Blob was uploaded successfully. requestId: ", uploadBlobResponse)
    
    if (err) return reject(err)
    //write to DB
    //end write to DB
    resolve(fields)
})

0

对于任何试图使用流的人,这对我有效:

import formidable from 'formidable';
import { PassThrough } from 'stream';

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
    if (req.method == 'POST') {
        const stream = new PassThrough();
        const form = new formidable.IncomingForm({
            fileWriteStreamHandler: () => {
                return stream;
            }
        });
        form.parse(req, (err, fields, files) => {
            if (files) {
                if (files['<form-file-input-name>']) {
                    const file = files['<form-file-input-name>'] as formidable.File;
                    const mimeType = file.mimetype;
                    const extension = file.originalFilename ? file.originalFilename.substring(file.originalFilename.lastIndexOf('.')) : '.csv';
                    const newFileName = `<form-file-input-name>-${new Date().toISOString()}${extension}`;
                    getFilesBlobContainer().getBlockBlobClient(newFileName).uploadStream(stream, undefined, undefined, {
                        blobHTTPHeaders: {
                            blobContentType: mimeType,
                        },
                    });
                }
            }
        });
        return res.status(200).end();
    }
}

export const config = {
    api: {
        bodyParser: false, //Disable NextJS body parsing so formidable can do that itself (fails silently otherwise)
    },
};

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接