我通过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还是字符串编码?
我相信问题来了,因为您正在将数据转换为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);
});
});