在节点损坏的情况下上传的图像 [英] Images uploaded with node corrupted
问题描述
我通过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屋!