上传的节点损坏的图像

问题描述 投票:0回答:1

我通过Next.js API路由上传的图像已损坏。我正在使用“强大”。

从我的React组件,我通过这些功能提交表单:

    const fileUpload = async (file: File) => {
        const url = '/api/image'
        const formData = new FormData()
        formData.append('file', file)
        const config = {
            headers: {
                'content-type': 'multipart/form-data',
            },
        }
        const response = await axios.post(url, formData, config)
        const { data } = response
        return data
    }

    const handleSubmit = async (event: React.SyntheticEvent) => {
        const url = '/api/post'
        if (files) {
                        // ignore 
            fileUpload(files[0]).then((response) =>
                console.log('submit response', response)
            )
        }
        event.preventDefault()
    }

Next中的API路由如下所示:

import formidable from 'formidable'
const fs = require('fs')
const { BlobServiceClient } = require('@azure/storage-blob')

if (process.env.NODE_ENV !== 'production') {
    require('dotenv').config()
}

const AZURE_STORAGE_CONNECTION_STRING =
    process.env.AZURE_STORAGE_CONNECTION_STRING

export const config = {
    api: {
        bodyParser: false,
    },
}

const getBlobName = (originalName) => {
    const identifier = Math.random().toString().replace(/0\./, '')
    return `${identifier}-${originalName}`
}

export default async (req, res) => {
    const form = new formidable.IncomingForm()
    form.keepExtensions = true
    form.uploadDir = './public/static/uploads'

    form.parse(req, async (err, fields, files) => {
        if (err) {
            return
        }
        return res.json({ fields, files })
    })

    form.on('file', async (name, file) => {
        const blobServiceClient = await BlobServiceClient.fromConnectionString(
            AZURE_STORAGE_CONNECTION_STRING
        )
        const containerClient = await blobServiceClient.getContainerClient(
            'images'
        )
        const buff = fs.readFileSync(file.path)
        const data = buff.toString('base64')

        const blobName = getBlobName(file.name)
        const blockBlobClient = containerClient.getBlockBlobClient(blobName)

        blockBlobClient.upload(data, data.length)
    })
}

被存储在本地的图像已损坏,看起来像是调谐到无效频道的电视。我显然没有正确编码-但不确定是我的ContentType还是字符串编码?

node.js reactjs typescript azure-storage-blobs next.js
1个回答
1
投票

我相信问题来了,因为您正在将数据转换为base64编码的字符串:

const data = buff.toString('base64')

考虑到您已经将上传的文件保存在服务器上的某个位置(此操作由formidable包完成,请尝试以下操作:

    const blobName = getBlobName(file.name)
    const blockBlobClient = containerClient.getBlockBlobClient(blobName)
    blockBlobClient.uploadFile(file.path)

[uploadFile()方法参考:https://docs.microsoft.com/en-gb/javascript/api/@azure/storage-blob/blockblobclient?view=azure-node-latest#uploadfile-string--blockblobparalleluploadoptions-

UPDATE

请尝试此代码。我刚刚尝试了这段代码,就能够成功上传文件。当我下载文件时,它没有损坏。

  form.on('file', async (name, file) => {
    const blobServiceClient = await BlobServiceClient.fromConnectionString(AZURE_STORAGE_CONNECTION_STRING);
    const containerClient = await blobServiceClient.getContainerClient('images');
    const blobName = file.name;
    const contentType = file.type;
    const filePath = file.path;
    const blockBlobClient = containerClient.getBlockBlobClient(blobName);
    const uploadBlobResponse = await blockBlobClient.uploadFile(file.path);
  });

更新#2

这是我使用的完整代码:

<form id="form1" method="post" action="/upload" enctype="multipart/form-data">
  <input name="file" type="file" id="file1" accept="image/*"/>
  <input type="button" id="button1" value="Upload" />
</form>


<script src="https://code.jquery.com/jquery-1.12.4.js" integrity="sha256-Qw82+bXyGq6MydymqBxNPYTaUXXq7c8v3CwiYwLLNXU=" crossorigin="anonymous"></script>

<script>
  $(document).on('ready', function() {

  });
  $('#button1').on('click', function(e) {
    data = new FormData();
    console.log($('#file1')[0].files[0]);
    data.append('file', $('#file1')[0].files[0]);
    console.log(data);
    $.ajax({
            url: '/upload',
            data: data,
            processData: false,
            contentType: false,
            type: 'POST',
            success: function ( data ) {
                alert( data );
            }
        });
    e.preventDefault();
    e.stopPropagation();
  });
</script>

var express = require('express'),
    path = require('path'),
    fs = require('fs'),
    formidable = require('formidable');
const { BlobServiceClient } = require('@azure/storage-blob');

var app = express();

app.set('port', (process.env.PORT || 5000));

// Tell express to serve static files from the following directories
app.use(express.static('public'));
app.use('/uploads', express.static('uploads'));

app.listen(app.get('port'), function() {
    console.log('Express started at port ' + app.get('port'));
});

app.get('/', function (req, res) {
    res.sendFile(path.join(__dirname, 'index.html'));
});


app.post('/upload', function(req, res) {
  const connectionString = 'DefaultEndpointsProtocol=https;AccountName=account-name;AccountKey=account-key;EndpointSuffix=core.windows.net;';
  const container = 'container-name';

  let form = new formidable.IncomingForm();
  form.keepExtensions = true;
  form.uploadDir = './public/static/uploads';
  form.parse(req, async function (err, fields, files) {
  });

  form.on('file', async (name, file) => {
    const blobServiceClient = await BlobServiceClient.fromConnectionString(connectionString);
    const containerClient = await blobServiceClient.getContainerClient(container);
    const blobName = file.name;
    const contentType = file.type;
    const filePath = file.path;
    console.log(file);
    const blockBlobClient = containerClient.getBlockBlobClient(blobName);
    const uploadBlobResponse = await blockBlobClient.uploadFile(file.path);
    console.log(uploadBlobResponse);
  });
});
© www.soinside.com 2019 - 2024. All rights reserved.