title: Upload HTML5 canvas image to server Angular2/Spring Boot
body: <p>I'm trying to upload HTML5 canvas image to server.
  Unfortunately when I convert canvas to blob and upload it to server I'm unable to open image.</p>
  
  <p>My implementation is working fine with following scenario a):</p>
  
  <ol>
  <li>Right click on canvas and Save as image to disk</li>
  <li>Select canvas image file form disk via input form with type="file"</li>
  <li>Send file selected in form via AJAX in FormData object</li>
  <li>Read upload file</li>
  </ol>
  
  <p><strong>Desired scenario b):</strong></p>
  
  <ol>
  <li>Get image data directly from canvas</li>
  <li>Send canvas data via AJAX in FormData object</li>
  <li>Read upload file</li>
  </ol>
  
  <p>When I open png file upload directly from canvas (scenario b) image is blank but I can see it has correct width and height.
  When I compare content with correct file in notepad files have the same begging/end but are different in the middle.
  The only difference in the requests is Content-Length.</p>
  
  <p>Technology Stack:
  Angular 2.4.6
  Spring Boot 1.5.2</p>
  
  <p>Scenario a) with file upload:</p>
  
  <pre><code>var files = event.srcElement.files;
  let formData = new FormData();
  formData.append('file', files[0], files[0].name);
  let headers = new Headers();
  headers.append('Authorization', currentUser.token);
  let options = new RequestOptions({ headers });
  this.http.post(this.apiUrl, formData, options)
      .map((response: Response) =&gt; {
          return response;
      })
      .catch(this.handleError);
  </code></pre>
  
  <p>Scenario a) request:</p>
  
  <pre><code>Request URL:http://localhost:8080/public/api/image
  Request Method:POST
  Status Code:200 
  Remote Address:[::1]:8080
  Referrer Policy:no-referrer-when-downgrade
  Response Headers
      view source
      Access-Control-Allow-Credentials:true
      Access-Control-Allow-Origin:http://localhost:3000
      Cache-Control:no-cache, no-store, max-age=0, must-revalidate
      Content-Length:0
      Content-Type:application/json;charset=ISO-8859-1
      Date:Fri, 21 Apr 2017 07:11:09 GMT
      Expires:0
      Pragma:no-cache
      Vary:Origin
      X-Content-Type-Options:nosniff
      X-Frame-Options:DENY
      X-XSS-Protection:1; mode=block
  Request Headers
      view source
      Accept:application/json, text/plain, */*
      Accept-Encoding:gzip, deflate, br
      Accept-Language:en-US,en;q=0.8,pl;q=0.6
      Authorization:eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJhZG1pbiIsImF1ZGllbmNlIjoid2ViIiwiY3JlYXRlZCI6MTQ5MjU0Nzc5OTYxMiwiZXhwIjoxNDkzMTUyNTk5fQ.YKhBf1bOS-egqLahtIFWI5t2vrAEbwHss96itIO8HanKU0V38XdOOY-ZJV41wE5oSqmOoGVUYXJMoxXYrLOzXw
      Connection:keep-alive
      Content-Length:25242
      Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryWh6h4VZ1UIs13Tal
      Host:localhost:8080
      Origin:http://localhost:3000
      Referer:http://localhost:3000/
      User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36
      Request Payload
      ------WebKitFormBoundaryWh6h4VZ1UIs13Tal
      Content-Disposition: form-data; name="file"; filename="download.png"
      Content-Type: image/png
  
  
  ------WebKitFormBoundaryWh6h4VZ1UIs13Tal--
  </code></pre>
  
  <p><strong>HERE IS THE PROBLEM Scenario b) with canvas content:</strong></p>
  
  <pre><code>let canvas = &lt;HTMLCanvasElement&gt; document.getElementById('main_canvas_container').firstElementChild;
          canvas.toBlob((blob) =&gt; {
      let formData = new FormData();
      formData.append('file', blob, 'file.png');
      let headers = new Headers();
      headers.append('Authorization', currentUser.token);
      let options = new RequestOptions({ headers });
      this.http.post(this.apiUrl, formData, options)
          .map((response: Response) =&gt; {
              return response;
          })
          .catch(this.handleError);
  }
  </code></pre>
  
  <p>Scenario b) request:</p>
  
  <pre><code>Request URL:http://localhost:8080/public/api/image
  Request Method:POST
  Status Code:200 
  Remote Address:[::1]:8080
  Referrer Policy:no-referrer-when-downgrade
  Response Headers
      view source
      Access-Control-Allow-Credentials:true
      Access-Control-Allow-Origin:http://localhost:3000
      Cache-Control:no-cache, no-store, max-age=0, must-revalidate
      Content-Length:0
      Content-Type:application/json;charset=ISO-8859-1
      Date:Fri, 21 Apr 2017 07:00:17 GMT
      Expires:0
      Pragma:no-cache
      Vary:Origin
      X-Content-Type-Options:nosniff
      X-Frame-Options:DENY
      X-XSS-Protection:1; mode=block
  Request Headers
      view source
      Accept:application/json, text/plain, */*
      Accept-Encoding:gzip, deflate, br
      Accept-Language:en-US,en;q=0.8,pl;q=0.6
      Authorization:eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJhZG1pbiIsImF1ZGllbmNlIjoid2ViIiwiY3JlYXRlZCI6MTQ5MjU0Nzc5OTYxMiwiZXhwIjoxNDkzMTUyNTk5fQ.YKhBf1bOS-egqLahtIFWI5t2vrAEbwHss96itIO8HanKU0V38XdOOY-ZJV41wE5oSqmOoGVUYXJMoxXYrLOzXw
      Connection:keep-alive
      Content-Length:11552
      Content-Type:multipart/form-data; boundary=----WebKitFormBoundarylO2dld6ISjr1W9E6
      Host:localhost:8080
      Origin:http://localhost:3000
      Referer:http://localhost:3000/
      User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36
      Request Payload
      ------WebKitFormBoundarylO2dld6ISjr1W9E6
      Content-Disposition: form-data; name="file"; filename="file.png"
      Content-Type: image/png
  
  
  ------WebKitFormBoundarylO2dld6ISjr1W9E6--
  </code></pre>
  
  <p>Server side:</p>
  
  <pre><code>@PostMapping("/public/api/image")
  public ResponseEntity&lt;String&gt; handleFileUpload(@RequestParam MultipartFile file) {
     try {
         Files.copy(file.getInputStream(), this.rootLocation.resolve(file.getOriginalFilename()));
     } catch (IOException e) {
         throw new StorageException("Failed to store file " + file.getOriginalFilename(), e);
     }
     return ResponseEntity.ok("");
  }
  </code></pre>