Chrome 65 блокирует <a загрузку> из разных источников. Обходной путь на стороне клиента для принудительной загрузки?

В Chrome 65 удалена поддержка атрибута downloadна анкерных элементах с перекрестным началом hrefs:

Block cross-origin <a download>

To avoid what is essentially a user-mediated cross-origin information leakage, Blink will now ignore the presence of the download attribute on anchor elements with cross origin attributes. Note that this applies to HTMLAnchorElement.download as well as to the element itself.

Intent to Remove | Chromestatus Tracker | Chromium Bug

Это нарушает бессерверные загрузки (для ресурсов из разных источников). Он также сломал кнопку сохранения изображения Reddit Enhancement Suite (.res-media-controls-download). RES v5.12.0 исправил это с помощью chrome.downloads API (расширение теперь запрашивает ваше разрешение на Управление загрузками)

Любой обходной путь?

Подробнее в Веб-спецификация, спасибо @jbmilgrom

🤔 А знаете ли вы, что...
Синтаксис JavaScript схож с синтаксисом языка программирования Java, но они не связаны.


36
19 226
2

Ответы:

Решено

Согласно обсуждение URL-адреса blob: и data: не затронуты, поэтому вот обходной путь с использованием fetch и Blobs.

Клиентская принудительная загрузка мультимедиа

function forceDownload(blob, filename) {
  var a = document.createElement('a');
  a.download = filename;
  a.href = blob;
  // For Firefox https://stackoverflow.com/a/32226068
  document.body.appendChild(a);
  a.click();
  a.remove();
}

// Current blob size limit is around 500MB for browsers
function downloadResource(url, filename) {
  if (!filename) filename = url.split('\\').pop().split('/').pop();
  fetch(url, {
      headers: new Headers({
        'Origin': location.origin
      }),
      mode: 'cors'
    })
    .then(response => response.blob())
    .then(blob => {
      let blobUrl = window.URL.createObjectURL(blob);
      forceDownload(blobUrl, filename);
    })
    .catch(e => console.error(e));
}

downloadResource('https://giant.gfycat.com/RemoteBlandBlackrussianterrier.webm');

Однако выборка работает только с некоторыми URL-адресами. Вы можете получить ошибку CORS:

Failed to load https://i.redd.it/l53mxu6n14o01.jpg: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://redditp.com' is therefore not allowed access.

Существуют расширения, которые позволяют перехватывать, изменять или удалять заголовки безопасности веб-сайтов:

UnXSS - Интернет-магазин Chrome

(Но установка Access-Control-Allow-Origin: * у меня сломала YouTube)

Представление

Обратите внимание, что этот подход не очень эффективен! Иногда у меня была остановка загрузки менее 1 минуты. Однако остальная часть страницы в это время была отзывчивой. Я не рассматривал это, но полагаю, что создание больших BLOB-объектов требует значительных ресурсов.

Violentmonkey / Tampermonkey

Если ваш вариант использования - это пользовательские скрипты, есть GM_download(options), GM_download(url, name)

⚠ В Tampermonkey это бета-функция, и вы должны сначала установить Режим загрузки: [Browser API ▾] в Панель управления Tampermonkey> Настройки

Tampermonkey Dashboard > Settings > Downloads


По-видимому, веб-спецификация в какой-то момент изменился, чтобы запретить загрузку из разных источников. Добавьте заголовок content-disposition: attachment в ответ, и загрузки из разных источников могут снова работать.