上传 HTML5 canvas 图像到服务器 Angular2/Spring 启动

Upload HTML5 canvas image to server Angular2/Spring Boot

我正在尝试将 HTML5 canvas 图片上传到服务器。 不幸的是,当我将 canvas 转换为 blob 并将其上传到服务器时,我无法打开图像。

我的实现在以下场景 a) 中运行良好:

  1. 右键单击 canvas 并另存为图像到磁盘
  2. Select canvas 图像文件磁盘通过类型为"file"
  3. 的输入表单
  4. 通过 AJAX 在 FormData 对象中发送在表单中选择的文件
  5. 读取上传文件

期望的场景 b):

  1. 直接从canvas
  2. 获取图像数据
  3. 通过 FormData 对象中的 AJAX 发送 canvas 数据
  4. 读取上传文件

当我打开直接从 canvas 上传的 png 文件时(场景 b)图像是空白的,但我可以看到它具有正确的宽度和高度。 当我将内容与记事本文件中的正确文件进行比较时,文件具有相同的 begging/end 但中间不同。 请求的唯一区别是 Content-Length。

技术栈: Angular2.4.6 Spring 引导 1.5.2

场景 a) 文件上传:

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) => {
        return response;
    })
    .catch(this.handleError);

场景a)请求:

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--

这是问题场景 b) canvas 内容:

let canvas = <HTMLCanvasElement> document.getElementById('main_canvas_container').firstElementChild;
        canvas.toBlob((blob) => {
    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) => {
            return response;
        })
        .catch(this.handleError);
}

场景b)请求:

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--

服务器端:

@PostMapping("/public/api/image")
public ResponseEntity<String> 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("");
}

事实证明,这是负责在我的 canvas (Blend4Web) 中呈现内容的框架的问题。当我直接从框架提供的方法中获取 blob 对象时,我能够毫无问题地上传文件。我分享的代码运行正常,可以作为参考。对花时间分析的人表示歉意