Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sending canvas.toDataURL() as FormData

I am trying to use html2canvas to render a DOM element as a .png image, which I then want to upload to the server. Here is my code:

import React, { Component, PropTypes } from 'react';
import html2canvas from 'html2canvas';
import axios from 'axios';


const sendScreenshot = (img) => {
  const config = {
      headers: {
          'content-type': 'multipart/form-data'
      }
  }
  let data = new FormData();
  data.append('screenshot', img);      
  return axios.post('/api/upload', data)
}

export default class Export extends Component {

  printDocument() {
    const input = document.getElementById('divToPrint');
    html2canvas(input).then(canvas => {
      document.body.appendChild(canvas);
      const imgData = canvas.toDataURL('image/png');
      sendScreenshot(imgData)
    });
  }

  ...

I can see that the DOM element is being converted to an image properly because I can see it appended to the page.

On the node.js server end, I can see that the form is coming through, but 'screenshot' is being received as a text field, not as a file. I am using multer and I confirmed that I can properly receive and save file uploads, at least when I use Postman.

So I guess the basic problem is that I need to indicate that the item I am appending to FormData is a file, not a text field. But I can't figure out how to do that. I tried using append with three arguments, and I tried converting the imgData into a blob like so:

const blob = new Blob([img], {type: 'image/png'});

But the results did not put me any closer to what I wanted.

like image 373
wbruntra Avatar asked Jan 10 '18 20:01

wbruntra


1 Answers

To send binary data in a POST request, you want to use a Blob. A Blob represents raw binary data. To get a Blob of a Canvas, you can use the toBlob method.

Once you have the Blob instance, you can add the Blob to the FormData using the append method. The append method accepts Blob instances as the second argument. You can even pass an optional third argument to append to specify the filename to send with the Blob to the server.

The blob will be received on the server as file data.

An example of this in action:

const canvas = document.getElementById('my-canvas');
canvas.toBlob(function(blob) {
  const formData = new FormData();
  formData.append('my-file', blob, 'filename.png');

  // Post via axios or other transport method
  axios.post('/api/upload', formData);
});
like image 139
Wazner Avatar answered Sep 22 '22 22:09

Wazner