将HTML5画布图像上传到服务器Angular2 / Spring Boot(Upload HTML5 canvas image to server Angular2/Spring Boot)
我正在尝试将HTML5画布图像上传到服务器。 不幸的是,当我将canvas转换为blob并将其上传到服务器时,我无法打开图像。
我的实现在以下方案a)中正常工作:
- 右键单击画布并将另存为图像到磁盘
- 通过type =“file”的输入表单选择画布图像文件表单磁盘
- 通过FormData对象中的AJAX发送在表单中选择的文件
- 阅读上传文件
期望的方案b):
- 直接从画布获取图像数据
- 在FormData对象中通过AJAX发送画布数据
- 阅读上传文件
当我直接从画布打开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):
- Right click on canvas and Save as image to disk
- Select canvas image file form disk via input form with type="file"
- Send file selected in form via AJAX in FormData object
- Read upload file
Desired scenario b):
- Get image data directly from canvas
- Send canvas data via AJAX in FormData object
- 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
最满意答案
你可以使用
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();
相关问答
更多-
如何在oracle数据库中创建触发器以便将来的日期无法设置?(How to create trigger in oracle database so that future date cannot set?)[2022-06-18]
尝试使用new来标识列: create or replace trigger test_trigger before insert on employees for each row BEGIN IF :new.patient_dob > sysdate THEN -------^ RAISE_APPLICATION_ERROR(-20950, 'date error'); END IF; END; Try using new to identify the colum ... -
$ ad_datefrom和$ ad_dateto是字符串格式,因此无法使用between子句。 使用php日期转换它们是这样的: $getSearch .= "AND cd.created_date BETWEEN '" . date("Y-m-d H:i:s", strtotime($ad_datefrom)) . "' AND '".date("Y-m-d H:i:s",strtotime($date))."' "; $getSearch .= "AND cd.created_date BETWE ...
-
为了限制在数据库旁边插入错误值,你应该使用@ api.constrains喜欢: @api.one @api.constrains('date_pub') def _check_date_pubd(self): if self.date_pub: if datetime.strptime(self.date_pub, DEFAULT_SERVER_DATE_FORMAT).date() < datetime.now().date(): raise Valida ...
-
考虑使用MS Access的DateValue函数只提取日期组件( TimeValue是时间组件对应)。 另外,考虑将日期值作为参数传递,以便与您的Python环境更好地集成,而不需要连接到Access' #表单。 下面通过一个参数作为一个项目的元组: from datetime import datetime ... cur.execute("SELECT * FROM MDSSDB WHERE DateValue([ValidStartTime]) = ?", (datetime(2016, 5, 1 ...
-
未来的日期选择(Future date picking)[2022-01-12]
这是一个完整的解决方案: