首页 \ 问答 \ 将HTML5画布图像上传到服务器Angular2 / Spring Boot(Upload HTML5 canvas image to server Angular2/Spring Boot)

将HTML5画布图像上传到服务器Angular2 / Spring Boot(Upload HTML5 canvas image to server Angular2/Spring Boot)

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

我的实现在以下方案a)中正常工作:

  1. 右键单击画布并将另存为图像到磁盘
  2. 通过type =“file”的输入表单选择画布图像文件表单磁盘
  3. 通过FormData对象中的AJAX发送在表单中选择的文件
  4. 阅读上传文件

期望的方案b):

  1. 直接从画布获取图像数据
  2. 在FormData对象中通过AJAX发送画布数据
  3. 阅读上传文件

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

技术堆栈:Angular 2.4.6 Spring Boot 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)与画布内容:

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("");
}

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.

My implementation is working fine with following scenario a):

  1. Right click on canvas and Save as image to disk
  2. Select canvas image file form disk via input form with type="file"
  3. Send file selected in form via AJAX in FormData object
  4. Read upload file

Desired scenario b):

  1. Get image data directly from canvas
  2. Send canvas data via AJAX in FormData object
  3. Read upload file

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.

Technology Stack: Angular 2.4.6 Spring Boot 1.5.2

Scenario a) with file upload:

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

Scenario a) request:

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

HERE IS THE PROBLEM Scenario b) with canvas content:

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);
}

Scenario b) request:

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

Server side:

@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("");
}

原文:https://stackoverflow.com/questions/43538362
更新时间:2023-09-18 20:09

最满意答案

你可以使用where表达式和>=运算符,如下所示:

DB::table('dates')
            ->where('date' , '>=' , Carbon::now()->toDateTimeString())->get();

You can use the where expression with >= operator like below:

DB::table('dates')
            ->where('date' , '>=' , Carbon::now()->toDateTimeString())->get();

相关问答

更多

相关文章

更多

最新问答

更多
  • 获取MVC 4使用的DisplayMode后缀(Get the DisplayMode Suffix being used by MVC 4)
  • 如何通过引用返回对象?(How is returning an object by reference possible?)
  • 矩阵如何存储在内存中?(How are matrices stored in memory?)
  • 每个请求的Java新会话?(Java New Session For Each Request?)
  • css:浮动div中重叠的标题h1(css: overlapping headlines h1 in floated divs)
  • 无论图像如何,Caffe预测同一类(Caffe predicts same class regardless of image)
  • xcode语法颜色编码解释?(xcode syntax color coding explained?)
  • 在Access 2010 Runtime中使用Office 2000校对工具(Use Office 2000 proofing tools in Access 2010 Runtime)
  • 从单独的Web主机将图像传输到服务器上(Getting images onto server from separate web host)
  • 从旧版本复制文件并保留它们(旧/新版本)(Copy a file from old revision and keep both of them (old / new revision))
  • 西安哪有PLC可控制编程的培训
  • 在Entity Framework中选择基类(Select base class in Entity Framework)
  • 在Android中出现错误“数据集和渲染器应该不为null,并且应该具有相同数量的系列”(Error “Dataset and renderer should be not null and should have the same number of series” in Android)
  • 电脑二级VF有什么用
  • Datamapper Ruby如何添加Hook方法(Datamapper Ruby How to add Hook Method)
  • 金华英语角.
  • 手机软件如何制作
  • 用于Android webview中图像保存的上下文菜单(Context Menu for Image Saving in an Android webview)
  • 注意:未定义的偏移量:PHP(Notice: Undefined offset: PHP)
  • 如何读R中的大数据集[复制](How to read large dataset in R [duplicate])
  • Unity 5 Heighmap与地形宽度/地形长度的分辨率关系?(Unity 5 Heighmap Resolution relationship to terrain width / terrain length?)
  • 如何通知PipedOutputStream线程写入最后一个字节的PipedInputStream线程?(How to notify PipedInputStream thread that PipedOutputStream thread has written last byte?)
  • python的访问器方法有哪些
  • DeviceNetworkInformation:哪个是哪个?(DeviceNetworkInformation: Which is which?)
  • 在Ruby中对组合进行排序(Sorting a combination in Ruby)
  • 网站开发的流程?
  • 使用Zend Framework 2中的JOIN sql检索数据(Retrieve data using JOIN sql in Zend Framework 2)
  • 条带格式类型格式模式编号无法正常工作(Stripes format type format pattern number not working properly)
  • 透明度错误IE11(Transparency bug IE11)
  • linux的基本操作命令。。。