NodeJS 将文件上载到Azure Blob存储时遇到困难

fhity93d  于 2023-08-04  发布在  Node.js
关注(0)|答案(1)|浏览(144)

我目前正在处理一个项目,我需要实现文件上传到Azure Blob存储。我已经使用Node.js和Express以及@azure/storage-blob库设置了后端。然而,我在前端实现方面遇到了困难,我可以使用一些指导来确保前端和后端正确集成。前端实现:我尝试使用React创建一个基本的前端,但是当我尝试将文件上传到服务器时遇到了400错误。我不确定我是否正确地构造了fetch()请求,或者FormData对象是否存在任何问题。文件选择和表单提交似乎工作正常,但上传的文件没有按预期到达后端。
Dashboard.jsx文件:

import React from 'react';
import { useState } from 'react';

function Dashboard() {
  const [selectedFile, setSelectedFile] = useState(null);

  const handleFileChange = (e) => {
    setSelectedFile(e.target.files[0]);
  };

  const handleFileUpload = async () => {
    try {
      const formData = new FormData();
      console.log(formData);
      formData.append('file', selectedFile);

      const response = await fetch('http://localhost:3000/api/upload', {
        method: 'POST',
        headers: {
          'Content-Type': 'multipart/form-data',
        },
        body: JSON.stringify({
          originalname: formData,
          mimetype: formData,
          size: formData
        }),
      });

      if (response.ok) {
        const data = await response.json();
        console.log(data.message);
        // You can handle success actions here if needed
      } else {
        console.error('File upload failed.');
        // You can handle error actions here if needed
      }
    } catch (error) {
      console.error('Error uploading file:', error);
    }
  };

  return (
    <div>
      <h1>File Upload</h1>
      <input type="file" onChange={handleFileChange} />
      <button onClick={handleFileUpload} disabled={!selectedFile}>
        Upload File
      </button>
    </div>
  );
}

export default Dashboard

字符串
后端实现:在后端,我已经设置了必要的路由来处理文件上传。我使用multer来处理文件解析和存储。后端代码使用@azure/storage-blob库与Azure Blob存储进行交互。然而,由于前端没有按预期运行,我无法验证后端是否正常工作。
uploadController.js文件:

const { BlobServiceClient, StorageSharedKeyCredential } = require('@azure/storage-blob');
const { v4: uuidv4 } = require('uuid');
const multer = require('multer');
const File = require('../models/files');

require('dotenv').config();

const sharedKeyCredential = new StorageSharedKeyCredential(
    process.env.AZURE_STORAGE_ACCOUNT_NAME,
    process.env.AZURE_STORAGE_ACCOUNT_KEY
);

const blobServiceClient = new BlobServiceClient(
    `https://${process.env.AZURE_STORAGE_ACCOUNT_NAME}.blob.core.windows.net`,
    sharedKeyCredential
);

const upload = multer({
    storage: multer.memoryStorage(),
});

exports.uploadFile = async (req, res, next) => {
    try{
        const file = req.file;
    if (!file) {
      return res.status(400).json({ error: 'Please upload a file!' });
    }

    // Generate a unique filename using UUID
    const uniqueFileName = `${uuidv4()}-${file.originalname}`;

    // Get a reference to the container
    const containerClient = blobServiceClient.getContainerClient(process.env.AZURE_CONTAINER_NAME);

    // Upload the file to Azure Blob Storage
    const blockBlobClient = containerClient.getBlockBlobClient(uniqueFileName);
    await blockBlobClient.uploadData(file.buffer, {
      blobHTTPHeaders: {
        blobContentType: file.mimetype,
        blobContentDisposition: `attachment; filename="${file.originalname}"`,
      },
    });

    // Save file information to the database
    const newFile = new File({
      filename: file.originalname,
      fileType: file.mimetype,
      fileSize: file.size,
      fileKey: uniqueFileName,
      fileURL: blockBlobClient.url,
    });

    await newFile.save();

    return res.status(201).json({ message: 'File uploaded successfully!', file: newFile });
    } catch (error) {
        console.log(error);
        return res.status(500).json({ error: 'Internal server error!' });
    }
}


我将非常感谢任何帮助,以改善我的前端代码的文件上传使用fetch()。此外,如果有人能检查我的后端代码并提出任何潜在的改进或调试步骤,那将是很有帮助的。
我将非常感谢任何帮助,以改善我的前端代码的文件上传使用fetch()。此外,如果有人能检查我的后端代码并提出任何潜在的改进或调试步骤,那将是很有帮助的。
我将非常感谢任何帮助改善我的前端代码的文件上传使用fetch()。此外,如果有人能检查我的后端代码并提出任何潜在的改进或调试步骤,那将是很有帮助的。

n53p2ov0

n53p2ov01#

  • 我对您的前端代码做了一些更改,可以将文件作为blob上传到我的存储帐户容器。*
    验证码:
    Dashboard.jsx:
import { useState } from 'react';
import axios from 'axios';

export default function FileUploader() {
  const [selectedFile, setSelectedFile] = useState(null);

  const handleFileUpload = async () => {
    if (selectedFile) {
      try {
        const reader = new FileReader();
        reader.readAsDataURL(selectedFile);
        reader.onloadend = async () => {
          const base64File = reader.result.split(',')[1];

          await axios.post('/api/upload', { base64File, filename: selectedFile.name });
        };
      } catch (error) {
        console.error(error);
      }
    }
  };

  const handleFileChange = (event) => {
    const file = event.target.files[0];
    setSelectedFile(file);
  };

  return (
    <div>
      <input type="file" accept=".txt" onChange={handleFileChange} />
      <button onClick={handleFileUpload}>Upload File to storage account</button>
    </div>
  );
}

字符串

upload.js:

import { BlobServiceClient } from '@azure/storage-blob';

export default async function handler(req, res) {
  if (req.method === 'POST') {
    try {
      const { base64File, filename } = req.body; 

      const storageAccount = '<storage_name>';
      const containerName = '<container_name>';
      const accessKey = '<storage_key>'; 
      const connectionString = `<connec_string>`;

      const blobServiceClient = BlobServiceClient.fromConnectionString(connectionString);

      const containerClient = blobServiceClient.getContainerClient(containerName);
      const fileBuffer = Buffer.from(base64File, 'base64');
      const blockBlobClient = containerClient.getBlockBlobClient(filename);
      await blockBlobClient.uploadData(fileBuffer, { blobHTTPHeaders: { blobContentType: 'text/plain' } });

      res.status(200).json({ message: 'File uploaded successfully' });
    } catch (error) {
      res.status(500).json({ error: 'Error occurred' });
    }
  } else {
    res.status(405).json({ error: 'Method not allowed' });
  }
}

index.js:

import FileUploader from '../components/Dashboard';

export default function Home() {
  return (
    <div>
      <h1>File Upload</h1>
      <FileUploader />
    </div>
  );
}

输出:

成功运行如下,


的数据
使用上面的输出URL,我在浏览器中得到了下面的内容。我点击【选择文件】,选择要上传的blob文件,点击【上传文件到存储账户】,


  • 文件以blob形式成功上传到我的存储账户容器,如下所示,*


相关问题