javascript - 无法在 javascript 中使用 fetch 发送大负载
问题描述
我是 JavaScript 和 NodeJS 领域的初学者。我试图用 NodeJS 创建一个简单的文件上传项目。此外,我在 NodeJS 中创建了路由并从网页中捕获图像并使用 fetch 将其发送到 NodeJS 路由。这是 HTML 文件:
<div class="file-upload">
<div class="image-upload-wrap">
<input class="file-upload-input" type='file' onchange="readURL(this);" accept="image/*" />
<div class="drag-text">
<h3>Drag and drop a file or select add Image</h3>
</div>
</div>
<div class="file-upload-content">
<div class="file-upload-display">
<img id="file-upload-image" class="file-upload-image" src="#" alt="your image" />
<div class="image-title-wrap">
<button type="button" onclick="removeUpload()" class="remove-image"><i class="fas fa-trash-alt"></i> Remove <span class="image-title">Uploaded Image</span></button>
</div>
</div>
</div>
</div>
<br>
<div class="file-upload-server d-flex justify-content-center">
<button class="btn btn-expand-lg btn-primary" onclick="uploadFile()"><i class="fas fa-cloud-upload-alt"></i> Upload</button>
</div>
这是我的 JavaScript 文件:
async function uploadFile() {
let img = document.getElementById('file-upload-image').src;
console.log('Image String Length: ' + img.length);
const payload = {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
file: img,
})
}
console.log(`Payload: ${JSON.stringify(payload)}`);
await fetch('http://localhost:3030/image/uploadimage', payload)
.then(response => response.json())
.then(data => {
console.log('Success:', data);
})
.catch((error) => {
console.error('Error:', error);
});
}
这里的图像是 base64 编码的字符串,我传递给我的 nodejs 路由。
当我单击上传按钮时,出现以下错误:
我已经用大小为 5.72kb 的图像测试了这段代码,它可以工作。但是当我尝试上传大小为 81.7kb 的图像时,它会因该错误而失败。
这是 nodejs 路线:
router.use(imageupload({
limits: { fileSize: 50 * 1024 * 1024 },
}));
router.use(express.urlencoded({limit: '50mb', extended: true}));
router.use(express.json());
const decodeBase64Image = (dataString) => {
let matches = dataString.match(/^data:([A-Za-z-+\/]+);base64,(.+)$/),
response = {};
if (matches.length !== 3) {
return new Error('Invalid input string');
}
response.type = matches[1];
response.data = Buffer.from(matches[2], 'base64');
return response;
}
router.post('/uploadimage', cors(corsOptions), async (req, res) => {
let decodedImage = decodeBase64Image(req.body.file);
let imageBuffer = decodedImage.data;
let type = decodedImage.type;
let extension = mime.getExtension(type);
let NewImageName = Math.random().toString(36).substring(7);
let fileName = 'image-' + NewImageName + '.' + extension;
try {
fs.writeFile(`${path.join(__dirname, '../')}/public/uploads/${fileName}`,
imageBuffer, function(err) {
if(err) throw err;
console.log('The file was uploaded successfully');
return res.status(200).json({status: 'success', message: 'File uploaded successfully'});
});
} catch(err) {
console.log(err);
return res.status(500).send(err);
}
});
任何有关这方面的帮助或指导都会很棒。
解决方案
我建议你应该使用 multer 这是一个链接
后端代码示例:
var multer = require('multer')
var signature = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, './public/')
},
filename: function (req, file, cb) {
if (file.mimetype == 'image/jpeg' || file.mimetype === 'image/jpg' || file.mimetype === 'image/png' || file.mimetype === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') {
cb(null, Date.now() + file.originalname)
} else {
cb({ error: 'Image type not supported' })
}
}
})
var uploadSignature = multer({ storage: signature })
router.put('/updateWorkOrderForSign',uploadSignature.array('signature', 1), function (req, res) {
try {
if (req.body.signature) {
var base64Data = req.body.signature.replace(/^data:image\/png;base64,/, "");
let rString = Math.random().toString(36).substring(7);
let date = Date.now();
let imageName = '/' + date + rString + '.png';
let imagePath = '/public' + imageName;
require("fs").writeFile('./' + imagePath, base64Data, 'base64', function (err) {
if (err) {
log.error('SAVE IMAGE FAILED WITH ERROR: ', err);
} else {
log.info('Signature image saved successfully')
}
});
} else {
//nothing to do
log.error("No signature image present")
}
} catch (err) {
log.error('ERROR WHILE CONVERTING BASE64 TO IMAGE: ', err);
}
})
前端代码示例(我已经在 react native 中实现了这个):
async function uploadFile() {
let imageObject = {
uri: image.path,
type: 'image/png',
name: 'signatureImage'
}
var form = new FormData();
form.append('signature', imageObject)
form.append(‘task’Id, taskId);
await fetch(urlStr, {
method: 'PUT',
headers: {
'Authorization': bearerToken,
Accept: 'application/json',
'Content-Type': 'multipart/form-data'},
body: params,
})
.then(response => response.json())
.then(responseData => {
var result = JSON.stringify(responseData);
return result;
})
.catch(error => {
console.log('ERROR WHILE UPLOADING IMAGE: ',error)
});
}
推荐阅读
- vb.net - Is there a way or event to retrieve command line arguments on runtime
- android - FirebaseAuthUserCollisionException vs FirebaseAuthInvalidUserException when user account is disabled?
- scala - 使用scala将DataFrame单行转换为Spark中的列
- c++ - Qt5.14 找不到“windows.h”头文件?
- html - 我无法让这个背景图像覆盖桌面视图中的整个高度
- ios - 从 URL 获取图像并将其附加到数组
- reactjs - 打字稿解析错误:尝试使用 Google Analytics 时需要“}”
- r - 在不同字段中仅按条件筛选一个值的组
- java - MongoTemplate 多条件查询不起作用
- mysql - 使用内连接在 SQL 查询中实现计数函数