首页 > 解决方案 > 无法在 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);
    }
});

任何有关这方面的帮助或指导都会很棒。

标签: javascriptnode.jsfetch-api

解决方案


我建议你应该使用 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)
                  });
}

推荐阅读