Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/google-chrome/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Google chrome Chrome和iOS Safari中正常图像的意外CORS问题_Google Chrome_Canvas_Cors - Fatal编程技术网

Google chrome Chrome和iOS Safari中正常图像的意外CORS问题

Google chrome Chrome和iOS Safari中正常图像的意外CORS问题,google-chrome,canvas,cors,Google Chrome,Canvas,Cors,我正面临一个让我发疯的CORS问题。请允许我共享一个示例URL: 由于每页只能复制一次该问题,以下是其他图像列表: 从该概述中,您可以打开任何照片页面。接下来,从该照片页面再次单击该图像以全屏启动它,因为这就是问题所在 现在请允许我解释一下设置和问题。该站点本身托管在我控制的Linux服务器上。该网站位于www.jungledragon.com。但是,这些图像存储在AmazonS3中,图像存储桶的别名为media.jungledragon.com 基本情况很简单: <div id="s

我正面临一个让我发疯的CORS问题。请允许我共享一个示例URL:

由于每页只能复制一次该问题,以下是其他图像列表:

从该概述中,您可以打开任何照片页面。接下来,从该照片页面再次单击该图像以全屏启动它,因为这就是问题所在

现在请允许我解释一下设置和问题。该站点本身托管在我控制的Linux服务器上。该网站位于www.jungledragon.com。但是,这些图像存储在AmazonS3中,图像存储桶的别名为media.jungledragon.com

基本情况很简单:

<div id="slideshow-image-container">
    <div class="slideshow-image-wrapper">
    <img src="http://media.jungledragon.com/images/1755/19907_large.jpg?AWSAccessKeyId=05GMT0V3GWVNE7GGM1R2&Expires=1409788810&Signature=QH26XDrVuhyr1Qimd7IOBsnui5s%3D" id="19907" class="img-slideshow img-sec wide" data-constrained="true" data-maxheight="2056" crossorigin="anonymous">
    </div>
</div>
虽然我相信我已经正确地设置了CORS,但我可以接受在某些浏览器中失败的代码。例如,它在Firefox和IE11中似乎运行良好。如果它失败了,我希望它无法计算主导色。然而,在非常特殊的情况下,更糟糕的事情正在发生:图像没有全部显示在一起

我的想法是,我通过img src标记“经典”加载图像应该与该脚本的工作或失败无关,在所有情况下,至少图像应该只加载,而不考虑画布技巧

下面是我发现图像没有加载到一起的情况,我认为这是一个主要的问题:

在iphone5的iOS7上,第一次加载工作正常。计算可能会失败,但会加载图像。刷新页面通常会破坏图像。第三次和第四次尝试,然后继续成功,依此类推

更糟糕的是,在Chrome 36中工作时,图像不能全部加载。我说在工作中,因为在家里这不是一个问题。可能是代理起了作用。我可以刷新所有我想要的,对于还没有运行计算的图像,它总是失败

接下来要做的自然事情是使用Chrome的inspector进行调试。你猜怎么着?当检查器打开时,它总是成功的。映像将始终加载,CORS请求头和响应看起来非常好。这让我几乎没有办法调试它。但我可以看出,当打开inspector时,当图像未加载时,控制台中会出现“CORS错误”,这是我之前请求的结果。打开inspector进行刷新将使其消失

通过阅读其他问题,我了解到缓存可能是一种影响,但更可能的问题在于源标题不是由浏览器发送的。我相信问题可能正朝着这个方向发展,但我无法理解这一点:

  • 它如何影响我使用img标签“正常”加载图像
  • 这仅仅是Chrome中的一个代理(据说)背后的一个问题,而且只有当inspector窗口关闭时才是问题
  • 它是如何在iOS上的Safari中如此不可靠和不一致地工作的
如前所述,我只能在一些浏览器中使用画布部分,但我不能在任何情况下都正常加载图像。那部分应该就行了

我意识到这种情况对你来说是难以置信的难以调试,但我希望我的解释能引发一些急需的帮助


更新:我发现,当我从img标签中删除crossorigin=“anonymous”时,图像将在我提到的特定场景中正确加载。然而,这一举措的结果是,颜色计算将不再适用于Chrome,无论是在家还是在工作中。不过,它在Firefox中仍能继续工作。我正在研究下一步该怎么办。

我自己设法解决了这个问题。我仍然无法在这里完全解释因果关系,但这就是我所做的:

我从html的img元素中删除了crossorigin=“anonymous”。这将至少确保始终加载图像

颜色计算第一部分通过基本重写其逻辑来解决:

var imgSrc = $('#<?= $bigimage['image_id'] ?>').attr('src');
    var cacheBurstPrefix = imgSrc.indexOf("?") > -1 ? '&' : '?';
    imgSrc += cacheBurstPrefix + 'ts=' + new Date().getTime();
    var imagePreloader = new Image();
    imagePreloader.crossOrigin = "Anonymous";
    imagePreloader.src = imgSrc;

    $(imagePreloader).imagesLoaded(function() {

        var rgb = getAverageRGB(imagePreloader);
        document.body.style.backgroundColor = 'rgb('+rgb.r+','+rgb.g+','+rgb.b+')';
        if (rgb!==false) {
            $.get(basepath + "image/<?= $bigimage['image_id'] ?>/setcolor/" + rgb.r + "-" + rgb.g + "-" + rgb.b);
        }

    });
var imgSrc=$('#').attr('src');
var cacheBurstPrefix=imgSrc.indexOf(“?”>-1?'&':“?”;
imgSrc+=cacheBurstPrefix+'ts='+new Date().getTime();
var imagepreload=新图像();
imagepreload.crossOrigin=“匿名”;
ImagePreload.src=imgSrc;
$(ImagePreload).imagesLoaded(函数(){
var rgb=getAverageRGB(图像预加载程序);
document.body.style.backgroundColor='rgb('+rgb.r+'、'+rgb.g+'、'+rgb.b+');
如果(rgb!==假){
$.get(basepath+“image//setcolor/”+rgb.r+“-”+rgb.g+“-”+rgb.b);
}
});
我没有重用html中的img元素,而是创建了一个新的内存中图像元素。使用缓存爆破技术,我确保它是新加载的。接下来,我将使用imagesLoaded(一个第三方插件)来检测加载内存中图像的事件,这比jQuery的load()事件要可靠得多

我已经进行了广泛的测试,可以确认在任何情况下,正常的图像加载都不会再次中断。它适用于所有浏览器和代理情况。作为额外的好处,颜色计算部分现在似乎可以在更多的浏览器中使用,包括一些移动浏览器


尽管我对根本原因仍然没有信心,但在经历了许多挫折之后,我对新的情况非常满意。

这是因为iOS在启用CORS的图像上存在一些奇怪的缓存问题。因此,如果使用[ImagePreload.crossOrigin=“Anonymous”]加载图像,并且该图像已被缓存,则加载将失败。
<script>
$( document ).ready(function() {

    <?php if (!$bigimage['dominantcolor']) { ?>

        $('#<?= $bigimage['image_id'] ?>').load(function(){
        var rgb = getAverageRGB(document.getElementById('<?= $bigimage['image_id'] ?>'));
        document.body.style.backgroundColor = 'rgb('+rgb.r+','+rgb.g+','+rgb.b+')';

        if (rgb!==false) {
            $.get(basepath + "image/<?= $bigimage['image_id'] ?>/setcolor/" + rgb.r + "-" + rgb.g + "-" + rgb.b);       
        }

        });

    <?php } ?>

});
function getAverageRGB(imgEl) {

    var blockSize = 5, // only visit every 5 pixels
    defaultRGB = {r:0,g:0,b:0}, // for non-supporting envs
    canvas = document.createElement('canvas'),
    context = canvas.getContext && canvas.getContext('2d'),
    data, width, height,
    i = -4,
    length,
    rgb = {r:0,g:0,b:0},
    count = 0;

    if (!context) {
        return defaultRGB;
    }

    height = canvas.height = imgEl.naturalHeight || imgEl.offsetHeight || imgEl.height;
    width = canvas.width = imgEl.naturalWidth || imgEl.offsetWidth || imgEl.width;

    imgEl.crossOrigin = "anonymous";

    context.drawImage(imgEl, 0, 0);

    try {
        data = context.getImageData(0, 0, width, height);
    } catch(e) {
        /* security error, img on diff domain */
        return false;
    }

    length = data.data.length;

    while ( (i += blockSize * 4) < length ) {
        ++count;
        rgb.r += data.data[i];
        rgb.g += data.data[i+1];
        rgb.b += data.data[i+2];
    }

    // ~~ used to floor values
    rgb.r = ~~(rgb.r/count);
    rgb.g = ~~(rgb.g/count);
    rgb.b = ~~(rgb.b/count);

    return rgb;

}
data = context.getImageData(0, 0, width, height);
var imgSrc = $('#<?= $bigimage['image_id'] ?>').attr('src');
    var cacheBurstPrefix = imgSrc.indexOf("?") > -1 ? '&' : '?';
    imgSrc += cacheBurstPrefix + 'ts=' + new Date().getTime();
    var imagePreloader = new Image();
    imagePreloader.crossOrigin = "Anonymous";
    imagePreloader.src = imgSrc;

    $(imagePreloader).imagesLoaded(function() {

        var rgb = getAverageRGB(imagePreloader);
        document.body.style.backgroundColor = 'rgb('+rgb.r+','+rgb.g+','+rgb.b+')';
        if (rgb!==false) {
            $.get(basepath + "image/<?= $bigimage['image_id'] ?>/setcolor/" + rgb.r + "-" + rgb.g + "-" + rgb.b);
        }

    });