Chrome 65 bloquea <una descarga> de origen cruzado. ¿Solución alternativa del lado del cliente para forzar la descarga?

Resuelto Leeroy asked hace 6 años • 2 respuestas

Chrome 65 eliminó la compatibilidad con el downloadatributo en elementos de anclaje con orígenes cruzadoshref :

Bloquear origen cruzado <una descarga>

Para evitar lo que es esencialmente una fuga de información de origen cruzado mediada por el usuario, Blink ahora ignorará la presencia del atributo de descarga en elementos de anclaje con atributos de origen cruzado. Tenga en cuenta que esto se aplica HTMLAnchorElement.downloadtanto al elemento mismo como al propio elemento.

Intención de eliminar | Rastreador de estado de Chrome | Error de cromo

Esto interrumpe las descargas sin servidor (para recursos de origen cruzado). También ha roto el botón para guardar imagen de Reddit Enhancement Suite ( .res-media-controls-download). RES v5.12.0 solucionó este problema usando la API chrome.downloads (la extensión ahora solicita su permiso para administrar descargas ) .

¿Alguna solución?

Más detalles en las especificaciones web , gracias @jbmilgrom

Leeroy avatar Mar 25 '18 17:03 Leeroy
Aceptado

Según la discusión blob: , data:las URL no se ven afectadas, por lo que aquí hay una solución alternativa usando fetchBlobs.

Medios de descarga forzada del lado del cliente

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');
Expandir fragmento

Sin embargo, la recuperación solo funciona en algunas URL. Es posible que obtenga un error 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.

Existen extensiones que le permiten interceptar, modificar o eliminar los encabezados de seguridad de los sitios web:

ModHeader - Tienda web de Chrome

(Pero la configuración Access-Control-Allow-Origin: *rompió YouTube para mí)

Actuación

¡Tenga en cuenta que este enfoque no es muy eficaz! A veces las descargas se detuvieron durante <1 minuto. Sin embargo, el resto de la página respondió durante este tiempo. No he investigado esto, pero imagino que la creación de Blobs grandes requiere muchos recursos.

Mono violento / Tampermonkey

Si su caso de uso son los scripts de usuario, hayGM_download(options), GM_download(url, name)

⚠ En Tampermonkey, esta es una función beta y primero debe configurar el Modo de descarga: [API del navegador ▾] en el Panel de control de Tampermonkey > Configuración

Panel de control de Tampermonkey > Configuración > Descargas

Leeroy avatar Mar 26 '2018 20:03 Leeroy

Aparentemente, la especificación web cambió en algún momento para no permitir descargas entre orígenes. Agregue content-disposition: attachmentun encabezado en la respuesta y las descargas entre orígenes pueden funcionar nuevamente.

jbmilgrom avatar Oct 30 '2018 00:10 jbmilgrom