是否可以通过编程检测数据url的大小限制? [英] Is it possible to programmatically detect size limit for data url?

查看:256
本文介绍了是否可以通过编程检测数据url的大小限制?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用javascript和html canvas来调整jpeg图片的大小。调整大小后,我使用 canvas.toDataURL 作为锚标记中的href属性,以提供一个链接,用户可以下载调整大小的图像。

I'm using javascript and html canvas to resize jpeg images. After resizing, I use canvas.toDataURL as the href attribute in an anchor tag in order to provide a link where users can download the resized images.

这样可以达到一定的图片大小。

This works nicely up to a certain image size.

似乎不同的浏览器对数据网址的大小有不同的限制,如下所示:
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/data_URIs

It seems that different browsers have different limits on the size of data urls as mentioned here: https://developer.mozilla.org/en-US/docs/Web/HTTP/data_URIs

在chrome中,当我超过数据url大小限制,当我点击下载链接没有任何反应;没有错误或任何东西(只要我能告诉)。

In chrome, when I'm over the data url size limit, nothing happens when I click on the download link; no errors or anything (as far as I can tell).

有没有办法以编程方式检测数据网址是否太大?也许某些浏览器事件会告诉我是否点击下载链接失败了?

Is there a some way to programmatically detect whether a data url is too large? Maybe some browser event that will show me whether clicking a download link failed?

理想情况下,我想检测下载是否成功。当数据网址太大时,我想向最终用户显示一个说明,描述如何右键单击该图像并选择另存为...,这似乎总是工作。

Ideally, I'd like to detect whether the download was successful. When data urls are too large, I'd like to display an explanation to the end user describing how to right click on the image and choose "save as ...", which always seems to work.

更新1:

看起来像使用 canvas.toBlob 是现在最好的解决方法。以下是api文档: https://developer.mozilla.org/ en-US / docs / Web / API / HTMLCanvasElement / toBlob

It looks like using canvas.toBlob is the best workaround for now. Here's the api documentation: https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob.

下面是一个jsfiddle,演示当使用 toDataURL 来显示较大的Canvase时, $ c> toBlob 似乎有效:

Here's a jsfiddle that demonstrates how anchor href download links fail when using toDataURL for larger canvases, but toBlob seems to work:

https://jsfiddle.net/upgradingdave/c76q34ac/3/

以下是一些相关的stackoverflow问题:
canvas.toDataURL()下载大小限制

Here are some related stackoverflow questions: canvas.toDataURL() download size limit

数据协议网址大小限制

推荐答案

不,似乎没有任何事件让你知道如果锚的下载属性实际上成功下载资源。

No, there doesn't seem to be any event letting you know if an anchor with the download attribute actually succeeded to download the resource.

但是,你面临的限制似乎只关注这种情况:锚元素< a> 下载属性。

But, the limitation you are facing seems to only concern this situation : an anchor element <a> with the download attribute.

浏览器可以处理更长的dataURI(我认为在大多数浏览器中,限制与字符串长度的限制相同)。例如,它可以加载到< img> 元素,更重要的是,在您的情况下,它可以处理dataURI字符串。

The browser can handle way longer dataURI (I think that in most browsers the limitation is the same as the one for strings length). E.g, it can load it to <img> element, and more importantly in your case, it can process the dataURI string.

这很重要,因为它允许您将此数据URL转换为blob,然后创建 对象URL 对象URL 的URI很小,并且在下载属性的锚点中不会遇到此长度限制。

This is important because it allows you to convert this dataURI to a blob, then to create an object URL from this blob. object URL's URI are small and don't face this length limitation in anchors with download attribute.

所以最好的情况是直接使用 canvas.toBlob 方法( a polyfill在mdn 上可用,并将对象URL 的URI作为您的锚的 href

So the best in your case is probably to directly use the canvas.toBlob method (a polyfill is available on mdn), and to pass the object URL's URI as the href of your anchor.

var img = new Image();
img.crossOrigin = "anonymous";

img.onload = function(){
  var ctx = document.createElement('canvas').getContext('2d');
  ctx.canvas.width = this.width*10;
  ctx.canvas.height = this.height*10;
  ctx.drawImage(this,0,0,ctx.canvas.width, ctx.canvas.height);
  // convert our canvas to a png blob 
  //  (for type use the second parameter, third is for quality if type is image/jpeg or image/webp)
  ctx.canvas.toBlob(function(blob){
     myAnchor.href = URL.createObjectURL(blob);
    });
  // since we are dealing with use files, we absolutely need to revoke the ObjectURL as soon as possible
  var revokeURL = function(){
    // but we have to wait that the browser actually prepared the file to download
    requestAnimationFrame(function(){
      // we've waited one frame, it's seems to be enough
      URL.revokeObjectURL(this.href);
      this.href=null;
      });
    this.removeEventListener('click', revokeURL);
    };

  myAnchor.addEventListener('click', revokeURL);
  };

img.src = 'http://lorempixel.com/200/200/';



<a id="myAnchor" download="anAwesomeImage.png">download</a>

[Live Demo] (由于下载属性被SE代码段中的某些UA封锁)

[ Live Demo ] (since download attribute is blocked by some UA in SE-Snippets)

但请注意,即使对象URL 的字符串表示(URI)很短,浏览器内存中文件的大小,直到您硬刷新页面(清除缓存),或关闭您创建此对象URL的选项卡。所以你绝对需要调用 URL.revokeObjectURL()来清除这个空间。

但是,由于没有事件知道下载实际上已成功,您将被 onclick 事件阻塞,这将在之前触发文件下载。从我的测试中,等待一个框架 requestAnimationFrame 就足够了,但我可能错了。

But note that even if the string representation (URI) of the object URL is short, it will actually take the size of your file in browser's memory, and so until you hard-refresh the page (clearing cache), or close the tab where you created this object URL. So you'll absolutely need to call URL.revokeObjectURL() to clear this space.
But, since there is no event to know if the downloading actually succeeded, you're stuck with the onclick event, which will fire before the file downloading occurred. From my tests, waiting for a single frame with requestAnimationFrame is enough, but I may be wrong.

对于那些来自其他来源而不是一个帆布为他们的dataURI,已经有很多的文章SO转换一个数据URL到一个Blob,你可以检查mdn polyfill上面提供,他们也做。

And for the ones coming here with an other source than a canvas for their dataURI, there are already a lot of posts in SO about converting a dataURI to a blob, and you can just check the mdn polyfill provided above, they're doing it too.

这篇关于是否可以通过编程检测数据url的大小限制?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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