在节点损坏的情况下上传的图像 [英] Images uploaded with node corrupted

查看:58
本文介绍了在节点损坏的情况下上传的图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Images I upload via Next.js API routes are corrupted. I am using Formidable.

我将从React组件通过以下功能提交表单:

From my React component I'm submitting a form via these functions:

    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路由如下所示:

And the API route in Next looks like this:

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还是字符串编码?

The image which gets stored locally is corrupt and looks like a TV tuned to a dead channel. I'm clearly not encoding it properly — but unsure whether it's my ContentType or the string encoding?

推荐答案

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

I believe the problem is coming because you're converting the data into a base64 encoded string:

const data = buff.toString('base64')

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

Considering you're already saving the uploaded file somewhere on the server (this is done by formidable package), please try something like:

    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- .

更新

请尝试使用此代码.我只是尝试了此代码,并且能够成功上传文件.当我下载文件时,它没有损坏.

Please try this code. I just tried this code and was able to upload the file successfully. When I downloaded the file, it was not corrupted.

  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


UPDATE #2

这是我使用的完整代码:

Here's the complete code I used:

<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);
  });
});

这篇关于在节点损坏的情况下上传的图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆