在retina.js库中抑制404s [英] Suppressing 404s in retina.js library

查看:81
本文介绍了在retina.js库中抑制404s的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们使用js lib retina.js 将低质量图像与视网膜图像交换(大小倍2)。问题是,retina.js为每个无法找到的视网膜图像抛出404.



我们拥有一个用户可以上传自己图片的网站最有可能不是视网膜分辨率。



有没有办法防止js抛出404s?



如果你不知道lib。以下是抛出404的代码:

  http = new XMLHttpRequest; 
http.open('HEAD',this.at_2x_path);
http.onreadystatechange = function(){
if(http.readyState!= 4){
return callback(false);
}

if(http.status> = 200&& http.status< = 399){
if(config.check_mime_type){
var type = http.getResponseHeader('Content-Type');
if(type == null ||!type.match(/ ^ image / i)){
return callback(false);
}
}

RetinaImagePath.confirmed_pa​​ths.push(that.at_2x_path);
返回回调(true);
} else {
返回回调(false);
}
}
http.send();


解决方案

我看到有几个选项可以缓解这个。



增强并保持retina.js的HTTP呼叫结果缓存



对于任何给定的'2x'图像设置为换出'1x'版本,retina.js首先通过 XMLHttpRequest 请求验证图像的可用性。成功响应的路径将缓存在一个数组中并下载图像。



以下更改可能会提高效率:




  • 失败 XMLHttpRequest 可以缓存验证尝试:目前,只有先前成功的'2x'路径验证尝试才会被跳过。因此,失败的尝试可能会再次发生。在实践中,这与初始加载页面时验证过程发生的情况无关。但是,如果结果持续存在,跟踪失败将防止重复发生404错误。


  • 坚持'2x'路径验证结果 localStorage :在初始化期间,retina.js可以检查 localStorage 以获取结果缓存。如果找到一个,则可以绕过已经遇到的2x图像的验证过程,并且可以下载或跳过2x图像。可以验证新遇到的2x图像路径,并将结果添加到缓存中。从理论上讲,虽然 localStorage 可用,但基于每个浏览器的图像只会出现一次404。这将适用于域上任何页面的页面。




这是一个快速的检查。可能需要添加到期功能。



https://gist.github.com/4343101/revisions



使用HTTP重定向标题



<我必须注意到,我对服务器端问题的掌握至多是 spotty 。请使用此FWIW



另一个选项是服务器使用重定向代码响应具有 @ 2x 字符,不存在。请参阅此相关答案



特别是:


如果您重定向图像并且它们是可缓存的,那么理想情况下,您可以为日期设置HTTP Expires标头(以及相应的Cache-Control标头)在遥远的未来,所以至少在后续访问页面时,用户不必再次进行重定向。


使用重定向响应将摆脱404并导致浏览器跳过后续尝试访问不存在的'2x'图像路径。



retina.js可以制作更具选择性



可以修改retinajs以排除某些图像。



与此相关的拉取请求: https://github.com/imulus/retinajs/commit/e7930be



根据拉取请求,而不是f按标签名称输入< img> 元素,可以使用CSS选择器,这可以是retina.js的可配置选项之一。可以创建一个CSS选择器来过滤掉用户上传的图像(以及预期不存在'2x'变体的其他图像)。



另一种可能性是为可配置选项添加过滤功能。可以在每个匹配的< img> 元素上调用该函数; a return true 会导致下载2x变体,而其他任何内容都会导致< img> 被跳过。



基本的默认配置将从当前版本类似于:

  var config = {
check_mime_type:true,
retinaImgTagSelector:'img',
retinaImgFilterFunc:undefined
};

Retina.init()函数会从当前版本更改为:

  Retina.init = function(context){
if(context == null)context = root;

var existing_onload = context.onload ||新功能;

context.onload = function(){
//使用新的查询选择器
var images = document.querySelectorAll(config.retinaImgTagSelector),
retinaImages = [] ,我,图像,过滤;

//如果有过滤器,请检查每个图像
if(typeof config.retinaImgFilterFunc ==='function'){
filter = config.retinaImgFilterFunc;
for(i = 0; i< images.length; i ++){
image = images [i];
if(filter(image)){
retinaImages.push(new RetinaImage(image));
}
}
} else {
for(i = 0; i< images.length; i ++){
image = images [i];
retinaImages.push(new RetinaImage(image));
}
}
existing_onload();
}
};

window.onload 火灾,打电话:

  window.Retina.configure({

//使用一个班级'no-retina'用于防止视网膜损伤
//检查视网膜版本
retinaImgTagSelector:'img:not(.no-retina)',

//或者,假设有一个数据所有者属性
//表示上传图像的用户:
// retinaImgTagSelector:'img:not([data-owner])',

//或设置一个过滤函数,它将排除具有
的图像//当前用户在其路径中的id,(假设在全局范围内有
//变量userId)
retinaImgFilterFunc:function(img){
return img.src.indexOf(window.userId)< 0;
}
});

更新:清理并重组。添加了 localStorage 增强功能。


We use the js lib retina.js which swaps low quality images with "retina" images (size times 2). The problem is, that retina.js throws a 404 for every "retina" image which can't be found.

We own a site where users can upload their own pictures which are most likely not in a retina resolution.

Is there no way to prevent the js from throwing 404s?

If you don't know the lib. Here is the code throwing the 404:

http = new XMLHttpRequest;
http.open('HEAD', this.at_2x_path);
http.onreadystatechange = function() {
    if (http.readyState != 4) {
        return callback(false);
    }

    if (http.status >= 200 && http.status <= 399) {
        if (config.check_mime_type) {
            var type = http.getResponseHeader('Content-Type');
            if (type == null || !type.match(/^image/i)) {
                return callback(false);
            }
        }

        RetinaImagePath.confirmed_paths.push(that.at_2x_path);
        return callback(true);
    } else {
        return callback(false);
    }
}
http.send();

解决方案

There are a few options that I see, to mitigate this.

Enhance and persist retina.js' HTTP call results caching

For any given '2x' image that is set to swap out a '1x' version, retina.js first verifies the availability of the image via an XMLHttpRequest request. Paths with successful responses are cached in an array and the image is downloaded.

The following changes may improve efficiency:

  • Failed XMLHttpRequest verification attempts can be cached: Presently, a '2x' path verification attempt is skipped only if it has previously succeeded. Therefore, failed attempts can recur. In practice, this doesn't matter much beacuse the verification process happens when the page is initially loaded. But, if the results are persisted, keeping track of failures will prevent recurring 404 errors.

  • Persist '2x' path verification results in localStorage: During initialization, retina.js can check localStorage for a results cache. If one is found, the verification process for '2x' images that have already been encountered can be bypassed and the '2x' image can either be downloaded or skipped. Newly encounterd '2x' image paths can be verified and the results added to the cache. Theoretically, while localStorage is available, a 404 will occur only once for an image on a per-browser basis. This would apply across pages for any page on the domain.

Here is a quick workup. Expiration functionality would probably need to be added.

https://gist.github.com/4343101/revisions

Employ an HTTP redirect header

I must note that my grasp of "server-side" matters is spotty, at best. Please take this FWIW

Another option is for the server to respond with a redirect code for image requests that have the @2x characters and do not exist. See this related answer.

In particular:

If you redirect images and they're cacheable, you'd ideally set an HTTP Expires header (and the appropriate Cache-Control header) for a date in the distant future, so at least on subsequent visits to the page users won't have to go through the redirect again.

Employing the redirect response would get rid of the 404s and cause the browser to skip subsequent attempts to access '2x' image paths that do not exist.

retina.js can be made more selective

retinajs can be modified to exclude some images from consideration.

A pull request related to this: https://github.com/imulus/retinajs/commit/e7930be

Per the pull request, instead of finding <img> elements by tag name, a CSS selector can be used and this can be one of the retina.js' configurable options. A CSS selector can be created that will filter out user uploaded images (and other images for which a '2x' variant is expected not to exist).

Another possibility is to add a filter function to the configurable options. The function can be called on each matched <img> element; a return true would cause a '2x' variant to be downloaded and anything else would cause the <img> to be skipped.

The basic, default configuration would change from the current version to something like:

var config = {
  check_mime_type: true,
  retinaImgTagSelector: 'img',
  retinaImgFilterFunc: undefined
};

The Retina.init() function would change from the current version to something like:

Retina.init = function(context) {
  if (context == null) context = root;

  var existing_onload = context.onload || new Function;

  context.onload = function() {
    // uses new query selector
    var images = document.querySelectorAll(config.retinaImgTagSelector), 
        retinaImages = [], i, image, filter;

    // if there is a filter, check each image
    if (typeof config.retinaImgFilterFunc === 'function') {
      filter = config.retinaImgFilterFunc;
      for (i = 0; i < images.length; i++) {
        image = images[i];
        if (filter(image)) {
          retinaImages.push(new RetinaImage(image));
        }
      }
    } else {
      for (i = 0; i < images.length; i++) {
        image = images[i];
        retinaImages.push(new RetinaImage(image));
      }
    }
    existing_onload();
  }
};

To put it into practice, before window.onload fires, call:

window.Retina.configure({

  // use a class 'no-retina' to prevent retinajs
  // from checking for a retina version
  retinaImgTagSelector : 'img:not(.no-retina)',

  // or, assuming there is a data-owner attribute
  // which indicates the user that uploaded the image:
  // retinaImgTagSelector : 'img:not([data-owner])',

  // or set a filter function that will exclude images that have
  // the current user's id in their path, (assuming there is a
  // variable userId in the global scope)
  retinaImgFilterFunc: function(img) {
    return img.src.indexOf(window.userId) < 0;
  }
});

Update: Cleaned up and reorganized. Added the localStorage enhancement.

这篇关于在retina.js库中抑制404s的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆