gpt4 book ai didi

javascript - Canvas 图像跨平台不安全错误

转载 作者:行者123 更新时间:2023-12-03 16:41:41 25 4
gpt4 key购买 nike

我有此代码用于从不同的服务器URL创建 Canvas 图像

function getBase64Image(imageUri) { 
var canvas = document.createElement("canvas");
ctx = canvas.getContext("2d");
var img = new Image();
img.src = imageUri;
img.crossOrigin = "Anonymous";
img.onload = function() {
canvas.width = this.width;
canvas.height = this.height;
ctx.drawImage(img, 0, 0, this.width, this.height);
var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
var dataURL = canvas.toDataURL("image/png");
document.getElementById("dummyhiddenField").value = dataURL;
};
}

我在哪里尝试从服务器获取图像并将其 Canvas URL设置为隐藏字段
但它只适用于本地镜像

根据从stackoverflow的其他答案,我设置了 crossOrigin = "Anonymous",它不起作用,也无法设置
从服务器访问源,必须管理localscript中的所有内容

谢谢

最佳答案

带有跨域内容的Html5 Canvas的更新外观。

以下是有关跨域内容如何影响html5 Canvas 以及如何在适用于跨域内容的安全限制内工作的最新信息

今天有一个有用的更新(2016年1月),因为有几种新的方法可以将跨域图像绘制到 Canvas 上而不会弄脏 Canvas 。

在html5 Canvas 上绘制跨域内容将导致它被“污染”。

您可以从 Canvas 上的另一个域绘制图像,它将显示在 Canvas 上。从另一个域访问资源称为“跨源资源共享”-简称为“CORS”。

出于安全原因,绘制CORS内容(例如:图像)将导致 Canvas 被“污染”。

如果 Canvas 被污染,则不能使用以下 Canvas 和上下文方法:

  • context.getImageData以获取 Canvas 上的像素数据
  • canvas.toDataURL将 Canvas 导出为图像

  • 您不能“欺骗” Canvas 违反其CORS安全限制-希望您甚至不想尝试!但是您可以通过满足CORS安全限制来绘制跨域图像而不会弄脏 Canvas 。

    处理图像以免弄脏 Canvas 的“通常”(也是最简单的)方法:

    将您的图片放置在与网页相同的 中。您可以有几台物理服务器来交付内容,但是图像 必须与创建 Canvas 的html代码(或javascript代码)相同。满足CORS限制,并且 Canvas 没有污染。

    在您自己的计算机上进行开发时有关CORS的说明

    解决方案#1(!):您可以在开发计算机上安装Web服务器,并从一个域提供Web页面文件(.html,.js等)和图像文件(.png,.jpg等)。

    您的开发计算机的文件夹被声明为不同的域。因此,从本地磁盘上的子目录绘制图像将违反CORS限制,因为不同的本地文件夹是不同的域。

    解决方案2:在进行开发时,您可以将网页文件和图像文件都放在桌面上,并且图像将被声明在同一域中,并且 Canvas 不会受到污染。

    当图像位于不同域时,满足CORS限制

    解决方案3:您 可以在 Canvas 上使用跨域图像而不会对其造成污染。为此,您必须满足以下要求:
  • 客户端:图像对象必须将crossOrigin属性设置为允许跨域内容。可以在html元素标记或javascript中设置此属性。启用设置为“匿名”和“使用凭证”。
  • 服务器端:必须将服务器配置为返回 header ,以指示响应中包含授权内容。

  • 根据配置,可能需要多个响应头:
    Access-Control-Allow-Origin将返回匿名授权( *)或根据请求返回特定的授权。

    如果身份验证需要其他信息(例如cookie),则需要 Access-Control-Allow-Credentials
    Access-Control-Expose-Headers使客户端可以访问其他响应信息。

    在服务器上启用跨域请求可能很复杂,尤其是在提供基于客户端角色授权的内容时。有关启动配置的其他信息,您可以访问: http://enable-cors.org/index.html

    使用允许匿名访问其图像的跨域图像主机

    解决方案4:一些公共(public)图像主机允许您上传图像,这些图像将以CORS兼容的方式提供给客户端。有几个示例: imgurdropbox。 Stackoverflow镜像托管在Imgur上。

    这是一个如何以符合CORS的方式在Dropbox.com上投放图片的示例:
  • 注册Dropbox Account
  • 为您提供几个默认文件夹。将图像上传到特殊的“公共(public)”文件夹中。这是Dropbox为CORS兼容匿名访问提供的文件夹。
  • 右键单击要提供的图像,然后选择“复制公共(public)链接”。您的剪贴板将包含指向您符合CORS的图片的链接。
  • 使用img标签或javascript将图像加载到页面上。

  • 这是使用javascript从Dropbox获取与CORS兼容的图像对象的示例代码:
    var img=new Image();
    img.crossOrigin='anonymous';
    img.src="https://dl.dropboxusercontent.com/u/139992952/multple/sun.png";
    img.onload=start;
    function start(){
    context.drawImage(img,0,0);
    // The canvas is not tainted so
    // the following both work without errors
    var url=canvas.toDataURL();
    var imageData=context.getImageData(0,0,100,100);
    }

    新增功能:通过让客户端用户表示同意来满足CORS的要求

    CORS安全限制旨在阻止恶意人员在不知情的情况下 secret 获取您的信息。

    直到最近,浏览器仍依靠客户端-服务器配置来满足安全性要求。最近,如果用户肯定地参与确定正在使用的内容,则浏览器已开始允许跨域内容。

    解决方案5:Chrome和Firefox现在允许客户端用户使用 right click the canvas & save the canvas as an image。这与使用 canvas.toDataURL创建图像对象并将该图像对象保存到本地驱动器的手动等效。 CORS之所以感到满意是因为用户决定了 Canvas 内容是否适合保存到本地驱动器,并且他们肯定地右键单击以启动下载过程。

    解决方案#6:可以使用 input element, type='file'让客户端用户选择图像。用户甚至可以选择一个Internet URL( http://..)。同样,由于用户参与了选择过程,CORS得到了满足。

    以下示例代码显示了如何侦听用户使用输入选择图像:

    // canvas vars
    var canvas=document.createElement("canvas");
    var ctx=canvas.getContext("2d");

    // define max resulting image width,height (after resizing)
    var maxW=100;
    var maxH=100;

    // listen for user to select files
    var input = document.getElementById('input');
    input.addEventListener('change', handleFiles);

    function handleFiles(e) {
    var img = new Image;
    img.onload = function(){
    var iw=img.width;
    var ih=img.height;
    // scale down, if necessary
    if(iw>maxW || ih>maxH){
    var scale=Math.min((maxW/iw),(maxH/ih));
    iw*=scale;
    ih*=scale
    }
    // set canvas width/height to scaled size
    canvas.width=iw;
    canvas.height=ih;
    // draw+scale the img onto the canvas
    ctx.drawImage(img,0,0,iw,ih);
    // create a jpeg URL (with medium quality to save "weight")
    var jpg=canvas.toDataURL('image/jpeg',0.60);
    // In Demo: add the jpg to the window
    // In production, accumulate jpg's & send to server
    $('<img />',{src:jpg}).appendTo('body');
    }
    // In Demo: Just process the first selected file
    // In production: process all selected files
    img.src = URL.createObjectURL(e.target.files[0]);
    }
    body{ background-color: ivory; }
    #canvas{border:1px solid red;}
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
    <h4>You can even enter a web URI (http://...)</h4>
    <input type="file" id="input"/><br>


    解决方案#7:您可以使用新的 FileReader,让用户选择要在 Canvas 上绘制的图像。

    // dropDiv event handlers
    var dropDiv=document.getElementById("dropDiv");
    dropDiv.addEventListener("dragenter", handleDragEnter, false);
    dropDiv.addEventListener("dragover", handleDragOver, false);
    dropDiv.addEventListener("drop", handleDrop, false);
    //
    function handleDragEnter(e) {
    e.stopPropagation();
    e.preventDefault();
    }
    //
    function handleDragOver(e) {
    e.stopPropagation();
    e.preventDefault();
    }
    //
    function handleDrop(e) {
    e.stopPropagation();
    e.preventDefault();

    var dt = e.dataTransfer;
    var files = dt.files;

    handleFiles(files);
    }

    //
    function handleFiles(files) {

    for (var i=0;i<files.length;i++) {
    var file = files[i];
    var imageType = /image.*/;

    if (!file.type.match(imageType)) {
    continue;
    }

    var img = document.createElement("img");
    img.classList.add("obj");
    img.file = file;
    preview.appendChild(img);

    var reader=new FileReader();
    reader.onload=(function(aImg){
    return function(e) {
    aImg.onload=function(){
    var canvas=document.createElement("canvas");
    var ctx=canvas.getContext("2d");
    canvas.width=aImg.width;
    canvas.height=aImg.height;
    ctx.drawImage(aImg,0,0);
    document.body.appendChild(canvas);
    }
    // e.target.result is a dataURL for the image
    aImg.src = e.target.result;
    };
    })(img);
    reader.readAsDataURL(file);

    } // end for

    } // end handleFiles

    function calcNewAspect(imgWidth, imgHeight, maxWidth, maxHeight) {
    var ratio = Math.min(maxWidth/imgWidth,maxHeight/imgHeight);
    return {width:imgWidth*ratio,height:imgHeight*ratio };
    }
    body{ background-color: ivory; }
    canvas{border:1px solid red;}
    #dropDiv{border:1px solid blue; width:300px;height:300px;}
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
    <h4>Drag 1+ image(s) from desktop to blue dropDiv.</h4>
    <div id="dropDiv"></div>
    <div id="preview"></div>


    待续...

    此更新中可能需要包含更多信息位。请随时对我的心不在comment发表评论,我将继续进行更新。 :-)

    关于javascript - Canvas 图像跨平台不安全错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34743987/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com