简体   繁体   English

Canvas.toDataURL() 受污染的画布可能无法导出

[英]Canvas.toDataURL() Tainted canvases may not be exported

I am trying to use javascript, html, css to create a page that I can resize an image from an online link.我正在尝试使用 javascript、html、css 创建一个页面,我可以通过在线链接调整图像大小。 However, when resized, I faced the error that Tainted canvases may not be exported while using Canvas.toDataURL() .但是,在调整大小时,我遇到了使用Canvas.toDataURL()时可能无法导出受污染画布的错误。 I have searched the issue in google and here.我已经在谷歌和这里搜索了这个问题。 Somebody suggested to amend the photo's crossorigin to anonymous or '*'.有人建议将照片的交叉来源修改为匿名或“*”。 I tried both methods but it doesn't work for me.我尝试了这两种方法,但对我不起作用。 I wonder anyone can offer help.我想知道任何人都可以提供帮助。 My code is in the below link.我的代码在下面的链接中。

https://jsfiddle.net/pangkachun/7axkq9pe/1/ https://jsfiddle.net/pangkachun/7axkq9pe/1/

 var min_img_width = 60; var min_img_height = 60; var max_img_width = 1000; var max_img_height = 1000; var resizeableImage = function(image_target) { // Some variable and settings var $container, orig_src = new Image(), image_target = $(image_target).get(0), event_state = {}, constrain = false, min_width = min_img_width, // Change as required min_height = min_img_height, max_width = max_img_width, // Change as required max_height = max_img_height, resize_canvas = document.createElement('canvas'), // ----------------- function to int the page ----------------------// init = function(){ // When resizing, we will always use this copy of the original as the base orig_src.src = image_target.src; orig_src.crossorigin = 'anonymous'; // Wrap the image with the container and add resize handles $(image_target).wrap('<div class="resize-container"></div>') .before('<span class="resize-handle resize-handle-nw"></span>') .before('<span class="resize-handle resize-handle-ne"></span>') .after('<span class="resize-handle resize-handle-se"></span>') .after('<span class="resize-handle resize-handle-sw"></span>'); // Assign the container to a variable $container = $(image_target).parent('.resize-container'); // Add events (one for resize (resize handle) and one for moving - img) // addEventListenor -> mouse touchdown, resize handle, resize_img $container.on('mousedown touchstart', '.resize-handle', startResize); }; // ------------------ end function to int the page -------------------------// // to save the data upon a event is fired saveEventState = function(e){ // Save the initial event details and container state event_state.container_width = $container.width(); event_state.container_height = $container.height(); event_state.container_left = $container.offset().left; event_state.container_top = $container.offset().top; event_state.mouse_x = (e.clientX || e.pageX || e.originalEvent.touches[0].clientX) + $(window).scrollLeft(); event_state.mouse_y = (e.clientY || e.pageY || e.originalEvent.touches[0].clientY) + $(window).scrollTop(); // This is a fix for mobile safari // For some reason it does not allow a direct copy of the touches property if(typeof e.originalEvent.touches !== 'undefined'){ event_state.touches = []; $.each(e.originalEvent.touches, function(i, ob){ event_state.touches[i] = {}; event_state.touches[i].clientX = 0+ob.clientX; event_state.touches[i].clientY = 0+ob.clientY; }); } event_state.evnt = e; }; // function to redraw the image based on width and height redrawImage = function(width, height){ resize_canvas.width = width; resize_canvas.height = height; resize_canvas.getContext('2d').drawImage(orig_src, 0, 0, width, height); $(image_target).attr('src', resize_canvas.toDataURL("image/png")); }; //------------------------ resizing function starts ----------------------------// startResize = function(e){ e.preventDefault(); e.stopPropagation(); saveEventState(e); $(document).on('mousemove touchmove', resizing); $(document).on('mouseup touchend', endResize); }; endResize = function(e){ e.preventDefault(); $(document).off('mouseup touchend', endResize); $(document).off('mousemove touchmove', resizing); }; resizing = function(e){ var mouse = {}, width, height, left, top, offset=$container.offset(); mouse.x = (e.clientX || e.pageX || e.originalEvent.touches[0].clientX) + $(window).scrollLeft(); mouse.y = (e.clientY || e.pageY || e.originalEvent.touches[0].clientY) + $(window).scrollTop(); // Position image differently depending on the corner dragged and constraints if( $(event_state.evnt.target).hasClass('resize-handle-se') ){ width = mouse.x - event_state.container_left; height = mouse.y - event_state.container_top; left = event_state.container_left; top = event_state.container_top; } else if($(event_state.evnt.target).hasClass('resize-handle-sw') ){ width = event_state.container_width - (mouse.x - event_state.container_left); height = mouse.y - event_state.container_top; left = mouse.x; top = event_state.container_top; } else if($(event_state.evnt.target).hasClass('resize-handle-nw') ){ width = event_state.container_width - (mouse.x - event_state.container_left); height = event_state.container_height - (mouse.y - event_state.container_top); left = mouse.x; top = mouse.y; if(constrain || e.shiftKey){ top = mouse.y - ((width / orig_src.width * orig_src.height) - height); } } else if($(event_state.evnt.target).hasClass('resize-handle-ne') ){ width = mouse.x - event_state.container_left; height = event_state.container_height - (mouse.y - event_state.container_top); left = event_state.container_left; top = mouse.y; } if(width > min_width && height > min_height && width < max_width && height < max_height){ // To improve performance you might limit how often resizeImage() is called redrawImage(width, height); // Without this Firefox will not re-calculate the the image dimensions until drag end $container.offset({'left': left, 'top': top}); } } //------------------------ resizing functino end ----------------------------// init(); }; resizeableImage($('.resize-image'));
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <!DOCTYPE html> <html lang="en" class="no-js"> <head> <title>Image Resizing with Canvas</title> <link rel="stylesheet" type="text/css" href="css/component.css" /> <!--[if IE]> <script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script> <![endif]--> </head> <body> <div class="container"> <div class="content"> <header class="codrops-header"> <h1>Image Resizing &amp; Cropping <br /><span>with Canvas</span></h1> </header> <div class="component"> <div class="overlay"> <div class="overlay-inner"> </div> </div> <img class="resize-image" id='test-img'crossorigin="anonymous" src="https://static-cdn.pixlr.com/images/image-design.png" alt="image for resizing"> </div> </div><!-- /content --> </div> <!-- /container --> <script src="js/jquery-2.1.1.min.js"></script> <script src="js/component.js"></script> </body> </html>

Thanks a lot.非常感谢。

There are a couple ways to get around this, but all of them will require at least temporarily hosting the image on your server.有几种方法可以解决这个问题,但所有这些方法都至少需要临时将图像托管在您的服务器上。 The simplest option would be to write a simple cgi script that takes an url as a parameter, fetches the image at that url, and sends it on to the browser as though it was on your server.最简单的选择是编写一个简单的 cgi 脚本,该脚本将一个 url 作为参数,从该 url 获取图像,然后将其发送到浏览器,就像它在您的服务器上一样。 You could also use a file upload form if you want the user to be able to select a local image.如果您希望用户能够选择本地图像,您还可以使用文件上传表单。

Note that if you do this, you would want to be aware of the security implications of grabbing user-selected files and serving them as if they were on your own server.请注意,如果您这样做,您可能希望了解获取用户选择的文件并将其作为在您自己的服务器上提供服务的安全隐患。 You would, at a minimum, want to make sure the files were valid images, and not, say, javascript files (which might lead to code injection attacks).您至少需要确保文件是有效的图像,而不是 javascript 文件(这可能会导致代码注入攻击)。

The reason exporting of tainted canvas data is disallowed is that it's a user security issue.不允许导出受污染的画布数据的原因是这是一个用户安全问题。 Remote sites can send different images to different users, and if your site can gain access to that just by drawing it on a canvas, that method could be used to steal a user's private data.远程站点可以向不同的用户发送不同的图像,如果您的站点可以通过在画布上绘制来访问该图像,则该方法可用于窃取用户的私人数据。 For example, Amazon used to let website owners embed an image in their site that would end up being a customized ad including a greeting and the end-user's name.例如,亚马逊曾经让网站所有者在他们的网站中嵌入一张图片,该图片最终会成为一个定制的广告,包括问候语和最终用户的姓名。 If you could paint that on a canvas and export the data, you could send that data back to your webserver and OCR it to learn the name of the end-user.如果您可以在画布上绘制并导出数据,则可以将该数据发送回您的网络服务器并对其进行 OCR 以了解最终用户的姓名。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 DOMException:无法在“HTMLCanvasElement”上执行“toDataURL”:可能无法导出受污染的画布 - DOMException: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported 未捕获的 DOMException:无法在“HTMLCanvasElement”上执行“toDataURL”:可能无法导出受污染的画布 - Uncaught DOMException: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported JavaScript:toDataUrl()抛出“安全错误:可能无法导出受污染的画布”。 - JavaScript: toDataUrl() throwing “Security Error: Tainted canvases may not be exported.” 受污染的画布不得出口 - Tainted canvases may not be exported 离线版本的 HTML2canvas - 受污染的画布可能无法导出 - HTML2canvas in offline version - Tainted canvases may not be exported 为什么收到错误“未捕获的SecurityError:无法在&#39;HTMLCanvasElement&#39;上执行&#39;toDataURL&#39;:错误的画布可能无法导出。 ” - Why am I getting the error “Uncaught SecurityError: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported. ” 从视频提升创建的画布“可能无法导出受污染的画布。” 保存时出错 - Canvas that created from video raising "Tainted canvases may not be exported." error when saving 带有 React 的 Tesseract.js:受污染的画布可能无法导出 - Tesseract.js with React: Tainted canvases may not be exported 可能无法导出空白的PNG /污染的画布(不使用图像) - Blank PNG / Tainted canvases may not be exported (not using images) Chrome:受污染的画布可能无法导出; 仅限离线应用 - Chrome: Tainted canvases may not be exported; Offline-only app
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM