无法在 javascript 中使用提取发送大负载
Unable to send large payload using fetch in javascript
我是 JavaScript 和 NodeJS space 的初学者。我试图用 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);
}
});
如果能对此提供任何帮助或指导,那就太好了。
您需要为 express.json()
中间件设置上传限制,因为您在 post 请求中使用 'Content-Type': 'application/json'
header。
尝试用 router.use(express.json({ limit: '50mb'})
替换 router.use(express.json())
编辑
如果您尝试使用 response.json()
解析未格式化为 json
的字符串,则会发生错误 Unexpected token < in JSON at position 0'
。您可以在 nodejs 中将其复制为 JSON.parse('I am no json...')
如果您在客户端上调用 response.json()
,它的格式必须正确 json
否则会导致错误。为此,请使用 res.json()
而不是 res.send()
。
您还应确保始终响应客户端,因此将 if(err) throw err;
行更改为
if(err) {
console.error(err)
// always send back a status, 500 means server error..
res.status(500).json('Internal server error')
return
}
我建议你在这里使用 multer a link
后端代码示例:
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)
});
}
我是 JavaScript 和 NodeJS space 的初学者。我试图用 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);
}
});
如果能对此提供任何帮助或指导,那就太好了。
您需要为 express.json()
中间件设置上传限制,因为您在 post 请求中使用 'Content-Type': 'application/json'
header。
尝试用 router.use(express.json({ limit: '50mb'})
router.use(express.json())
编辑
如果您尝试使用 response.json()
解析未格式化为 json
的字符串,则会发生错误 Unexpected token < in JSON at position 0'
。您可以在 nodejs 中将其复制为 JSON.parse('I am no json...')
如果您在客户端上调用 response.json()
,它的格式必须正确 json
否则会导致错误。为此,请使用 res.json()
而不是 res.send()
。
您还应确保始终响应客户端,因此将 if(err) throw err;
行更改为
if(err) {
console.error(err)
// always send back a status, 500 means server error..
res.status(500).json('Internal server error')
return
}
我建议你在这里使用 multer a link
后端代码示例:
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)
});
}