Ответ 1
Нет, похоже, нет никакого события, позволяющего узнать, действительно ли привязка с атрибутом download
удалось загрузить ресурс.
Но ограничение, с которым вы сталкиваетесь, похоже, касается только этой ситуации: якорный элемент <a>
с атрибутом download
.
Браузер может обрабатывать более длинный dataURI (я думаю, что в большинстве браузеров ограничение такое же, как и для длины строк). Например, он может загрузить его в элемент <img>
, и, что более важно, в вашем случае, он может обрабатывать строку dataURI.
Это важно, потому что это позволяет вам преобразовать этот dataURI в blob, а затем создать object URL
из этого блоба. object URL
URI являются малыми и не сталкиваются с этим ограничением длины в якорях с атрибутом download
.
Итак, лучше всего в вашем случае, вероятно, использовать метод canvas.toBlob
(a polyfill доступен на mdn) и передать object URL
URI как href
вашего якоря.
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 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] (поскольку атрибут download
заблокирован некоторым UA в SE- Отрывки)суб >
Но обратите внимание, что даже если строковое представление (URI) object URL
является коротким, оно фактически примет размер вашего файла в памяти браузера, и пока вы не обновите страницу (очистка кеша) или закройте вкладку, где вы создали этот URL-адрес объекта. Поэтому вам нужно будет позвонить URL.revokeObjectURL()
, чтобы очистить это пространство.
Но, поскольку нет никакого события, чтобы узнать, действительно ли загрузка действительно удалась, вы застряли в событии onclick
, в котором будет срабатывать до, при загрузке файла. Из моих тестов ждать одного кадра с requestAnimationFrame
достаточно, но я могу ошибаться.
И для тех, кто приходит сюда с другим источником, кроме холста для своих данныхURI, в SO уже есть много сообщений о преобразовании dataURI в blob, и вы можете просто проверить приведенный выше mdn polyfill они тоже делают это.