Wymuś przeglądarkę, aby pobierała pliki obrazów jednym kliknięciem

100

Potrzebuję przeglądarki, aby pobrać pliki obrazów, tak jak robi to podczas klikania arkusza Excel.

Czy można to zrobić tylko przy użyciu programowania po stronie klienta?

<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title></title>
        <script type="text/javascript" src="Scripts/jquery-1.10.2.js">
        $(document).ready(function () {
            $("*").click(function () {
                $("p").hide();
            });
        });
        </script>
    </head>

    <script type="text/javascript">
        document.onclick = function (e) {
            e = e || window.event;
            var element = e.target || e.srcElement;
            if (element.innerHTML == "Image") {
                //someFunction(element.href);
                var name = element.nameProp;
                var address = element.href;
                saveImageAs1(element.nameProp, element.href);
                return false; // Prevent default action and stop event propagation
            }
            else
                return true;
        };

        function saveImageAs1(name, adress) {
            if (confirm('you wanna save this image?')) {
                window.win = open(adress);
                //response.redirect("~/testpage.html");
                setTimeout('win.document.execCommand("SaveAs")', 100);
                setTimeout('win.close()', 500);
            }
        }
    </script>

    <body>
        <form id="form1" runat="server">
            <div>
                <p>
                    <a href="http://localhost:55298/SaveImage/demo/Sample2.xlsx" target="_blank">Excel</a><br />
                    <a href="http://localhost:55298/SaveImage/demo/abc.jpg" id="abc">Image</a>
                </p>
            </div>
        </form>
    </body>
</html>

Jak powinno działać w przypadku pobrania arkusza Excela (jakie przeglądarki robią)?

Amit
źródło
7
downloadAtrybut.
Šime Vidas,
6
Najlepszym sposobem zapewnienia pobierania plików jest ustawienie rozmieszczenia treści na serwerze, większość rozwiązań po stronie klienta nie jest tak niezawodna.
adeneo,
1
Możliwy duplikat: stackoverflow.com/questions/2408146/… ?
Karl-André Gagnon,
Jest podobne pytanie, na które już dla Ciebie udzielono odpowiedzi: stackoverflow.com/a/6799284/1948211
dschu
Karl-André Gagnon: Proszę przejść przez niego properply [i nie określili HTML 5 jak nie chcę go używać] i W / O Server ramionami.
Amit

Odpowiedzi:

172

Korzystając z HTML5, możesz dodać atrybut „pobierz” do swoich linków.

<a href="https://stackoverflow.com/path/to/image.png" download>

Zgodne przeglądarki wyświetlą wówczas monit o pobranie obrazu o tej samej nazwie pliku (w tym przykładzie image.png).

Jeśli określisz wartość tego atrybutu, stanie się on nową nazwą pliku:

<a href="https://stackoverflow.com/path/to/image.png" download="AwesomeImage.png">

UPDATE: Jak wiosny 2018 nie jest to już możliwe dla cross-pochodzenie hrefs . Więc jeśli chcesz utworzyć <a href="https://i.imgur.com/IskAzqA.jpg" download>w domenie innej niż imgur.com, nie będzie działać zgodnie z przeznaczeniem. Ogłoszenie o wycofaniu i usunięciu Chrome

Richard Parnaby-King
źródło
Richard Parnaby-King: Używając atrybutu HTML 5 można to zrobić, ale muszę to zrobić BEZ użycia HTML5 lub jakichkolwiek narzędzi SERVER SIDE (jeśli to możliwe) Dziękuję za pomocników :)
Amit
2
Nie jest jeszcze w pełni obsługiwany we wszystkich przeglądarkach, ale jest dobrym rozwiązaniem, jeśli nie interesuje Cię IE lub Safari. caniuse.com/#feat=download
stacigh
Dzięki za rozwiązanie HTML5. Jak nadal zezwolić na „zapisz jako”, co pozwoli mi wprowadzić nazwę pliku przed zapisaniem?
teleman 22.07.15
Nie mogę kontrolować, gdzie powinien zostać pobrany ten plik? Wystarczy pobrać, aby bezpośrednio pobrać folder. Chcę, aby używała lokalnej ścieżki pliku html.
Arjun Chiddarwar
1
@ArjunChiddarwar Nie, to otwiera luki w zabezpieczeniach (wyobraź sobie, że ktoś zapisuje złośliwy plik bezpośrednio w folderze Windows). Ścieżka pobierania jest oparta na ustawieniach przeglądarki - na przykład domyślnie Chrome pobierze się do folderu pobierania.
Richard Parnaby-King
96

Udało mi się to uruchomić również w Chrome i Firefox, dołączając link do dokumentu.

var link = document.createElement('a');
link.href = 'images.jpg';
link.download = 'Download.jpg';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
DrowsySaturn
źródło
2
W rzeczywistości jest to bardzo fajne rozwiązanie dla aplikacji internetowych, w których Javascript jest wszędzie. Działa jednak tylko w Google Chrome (w mojej konfiguracji testowej).
Pavel
Jakieś pomysły dotyczące sposobu sprawdzenia zgodności? Chciałbym użyć tej techniki, ale muszę obsługiwać również inne przeglądarki, więc musiałbym zaoferować alternatywę (np. Otwarcie pliku PDF w nowym oknie lub łącze do pobrania), gdy nie jest to obsługiwane. Czy ktoś miał z tym szczęście?
alexrussell
13
Świetne rozwiązanie, dzięki! Zauważ, że jeśli pominiesz, document.body.appendChild(link)nie będzie działać w przeglądarce Firefox. Dobrze jest też usunąć utworzony element za pomocą document.body.removeChild(link);afterlink.click()
akn
8
najlepsze rozwiązanie. Aby uniknąć śmieci w używaniu DOMsetTimeout( function () { link.parentNode.removeChild( link ); },10 );
Mephiztopheles
1
Dziękuję, powinno być wybraną odpowiedzią, ponieważ pytanie, jak to zrobić w JAVASCRIPT.
codehelp4
33

Leeroy i Richard Parnaby-King:

AKTUALIZACJA: Od wiosny 2018 nie jest to już możliwe dla hrefów pochodzących z różnych źródeł. Więc jeśli chcesz utworzyć w domenie innej niż imgur.com, nie będzie działać zgodnie z przeznaczeniem. Ogłoszenie o wycofaniu i usunięciu Chrome

function forceDownload(url, fileName){
    var xhr = new XMLHttpRequest();
    xhr.open("GET", url, true);
    xhr.responseType = "blob";
    xhr.onload = function(){
        var urlCreator = window.URL || window.webkitURL;
        var imageUrl = urlCreator.createObjectURL(this.response);
        var tag = document.createElement('a');
        tag.href = imageUrl;
        tag.download = fileName;
        document.body.appendChild(tag);
        tag.click();
        document.body.removeChild(tag);
    }
    xhr.send();
}
iXs
źródło
2
obraz jest pobierany, ale nie otwiera się, jak jest
napisane
19

Zaktualizuj wiosnę 2018 r

<a href="/path/to/image.jpg" download="FileName.jpg">

Chociaż jest to nadal obsługiwane, od lutego 2018 r. Chrome wyłączył tę funkcję dla pobierania z różnych źródeł, co oznacza, że ​​będzie działać tylko wtedy, gdy plik znajduje się w tej samej nazwie domeny.

Znalazłem obejście problemu pobierania obrazów z wielu domen po nowej aktualizacji Chrome, która wyłączyła pobieranie z wielu domen. Możesz zmodyfikować to w funkcję dostosowaną do swoich potrzeb. Możesz być w stanie uzyskać obraz typu MIME (jpeg, png, gif, itp.) Po przeprowadzeniu dalszych badań, jeśli zajdzie taka potrzeba. Może istnieć sposób na zrobienie czegoś podobnego z filmami. Mam nadzieję, że to komuś pomoże!

Leeroy i Richard Parnaby-King:

AKTUALIZACJA: Od wiosny 2018 nie jest to już możliwe dla hrefów pochodzących z różnych źródeł. Więc jeśli chcesz utworzyć w domenie innej niż imgur.com, nie będzie działać zgodnie z przeznaczeniem. Ogłoszenie o wycofaniu i usunięciu Chrome

var image = new Image();
image.crossOrigin = "anonymous";
image.src = "https://is3-ssl.mzstatic.com/image/thumb/Music62/v4/4b/f6/a2/4bf6a267-5a59-be4f-6947-d803849c6a7d/source/200x200bb.jpg";
// get file name - you might need to modify this if your image url doesn't contain a file extension otherwise you can set the file name manually
var fileName = image.src.split(/(\\|\/)/g).pop();
image.onload = function () {
    var canvas = document.createElement('canvas');
    canvas.width = this.naturalWidth; // or 'width' if you want a special/scaled size
    canvas.height = this.naturalHeight; // or 'height' if you want a special/scaled size
    canvas.getContext('2d').drawImage(this, 0, 0);
    var blob;
    // ... get as Data URI
    if (image.src.indexOf(".jpg") > -1) {
    blob = canvas.toDataURL("image/jpeg");
    } else if (image.src.indexOf(".png") > -1) {
    blob = canvas.toDataURL("image/png");
    } else if (image.src.indexOf(".gif") > -1) {
    blob = canvas.toDataURL("image/gif");
    } else {
    blob = canvas.toDataURL("image/png");
    }
    $("body").html("<b>Click image to download.</b><br><a download='" + fileName + "' href='" + blob + "'><img src='" + blob + "'/></a>");
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Riley Bell
źródło
Wygląda na to, że ten kod dekoduje obraz do bufora pikseli w pamięci przeglądarki, a następnie ponownie koduje go jako jpeg / png / gif, a następnie hermetyzuje go w danych-uri, który, miejmy nadzieję, jest następnie przechowywany lokalnie. Jeśli tak, oznacza to, że wszystkie metadane z pliku obrazu zostaną utracone. Również ponowne kodowanie JPEG spowoduje utratę jakości i gorszy stosunek jakości do liczby bajtów. Mimo wszystko dobrze wiedzieć. Dzięki za udostępnienie.
Stéphane Gourichon
14

Bardziej nowoczesne podejście wykorzystujące Promise i async / await:

toDataURL(url) {
    return fetch(url).then((response) => {
            return response.blob();
        }).then(blob => {
            return URL.createObjectURL(blob);
        });
}

następnie

async download() {
        const a = document.createElement("a");
        a.href = await toDataURL("https://cdn1.iconfinder.com/data/icons/ninja-things-1/1772/ninja-simple-512.png");
        a.download = "myImage.png";
        document.body.appendChild(a);
        a.click();
        document.body.removeChild(a);
}

Znajdź dokumentację tutaj: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch

Emerica
źródło
13
var pom = document.createElement('a');
pom.setAttribute('href', 'data:application/octet-stream,' + encodeURIComponent(text));
pom.setAttribute('download', filename);
pom.style.display = 'none';
document.body.appendChild(pom);
pom.click();
document.body.removeChild(pom);     
Sadi
źródło
5
przeglądarka safari nie obsługuje atrybutu pobierania
Pranav Labhe
11

To jest ogólne rozwiązanie twojego problemu. Ale jest jedna bardzo ważna część, że rozszerzenie pliku powinno pasować do twojego kodowania. I oczywiście ten parametr zawartości funkcji downlowadImage powinien być ciągiem zakodowanym w base64 twojego obrazu.

const clearUrl = url => url.replace(/^data:image\/\w+;base64,/, '');

const downloadImage = (name, content, type) => {
  var link = document.createElement('a');
  link.style = 'position: fixed; left -10000px;';
  link.href = `data:application/octet-stream;base64,${encodeURIComponent(content)}`;
  link.download = /\.\w+/.test(name) ? name : `${name}.${type}`;

  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);
}

['png', 'jpg', 'gif'].forEach(type => {
  var download = document.querySelector(`#${type}`);
  download.addEventListener('click', function() {
    var img = document.querySelector('#img');

    downloadImage('myImage', clearUrl(img.src), type);
  });
});
a gif image: <image id="img" src="data:image/gif;base64,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" />


<button id="png">Download PNG</button>
<button id="jpg">Download JPG</button>
<button id="gif">Download GIF</button>

hakobpogh
źródło
3
Dodaj krótkie wyjaśnienie do swojej odpowiedzi, aby była ona odpowiednia dla osoby, która ją zadała
WIEK
1
link.href = 'data: application / octet-stream,' + encodeURIComponent (adres) to uszkadza plik i dlatego nie można go otworzyć, canu sugeruje, dlaczego tak jest
OM The Eternity
Tak, ta odpowiedź zasługuje na to, by być najlepszą! Brakowało mi elementu „cleanUrl”, który generował zniekształcone dane i uszkadzał plik.
Iulian Pinzaru
3

W 2020 używam Bloba do tworzenia lokalnej kopii obrazu, którą przeglądarka pobierze jako plik. Możesz to przetestować na tej stronie .

wprowadź opis obrazu tutaj

(function(global) {
  const next = () => document.querySelector('.search-pagination__button-text').click();
  const uuid = () => Math.random().toString(36).substring(7);
  const toBlob = (src) => new Promise((res) => {
    const img = document.createElement('img');
    const c = document.createElement("canvas");
    const ctx = c.getContext("2d");
    img.onload = ({target}) => {
      c.width = target.naturalWidth;
      c.height = target.naturalHeight;
      ctx.drawImage(target, 0, 0);
      c.toBlob((b) => res(b), "image/jpeg", 0.75);
    };
    img.crossOrigin = "";
    img.src = src;
  });
  const save = (blob, name = 'image.png') => {
    const a = document.createElement("a");
    a.href = URL.createObjectURL(blob);
    a.target = '_blank';
    a.download = name;
    a.click();
  };
  global.download = () => document.querySelectorAll('.search-content__gallery-results figure > img[src]').forEach(async ({src}) => save(await toBlob(src), `${uuid()}.png`));
  global.next = () => next();
})(window);
Petr Tripolsky
źródło
Wygląda na to, że ten kod dekoduje obraz do bufora pikseli (płótna) w pamięci przeglądarki, a następnie ponownie koduje go jako jpeg / png / gif, a następnie hermetyzuje go w URI danych, który, miejmy nadzieję, jest następnie przechowywany lokalnie. Jeśli tak, oznacza to, że wszystkie metadane z pliku obrazu zostaną utracone. Również ponowne kodowanie JPEG spowoduje utratę jakości i gorszy stosunek jakości do liczby bajtów. Mimo wszystko dobrze wiedzieć. Dzięki za udostępnienie.
Stéphane Gourichon
2

Spróbuj tego:

<a class="button" href="http://www.glamquotes.com/wp-content/uploads/2011/11/smile.jpg" download="smile.jpg">Download image</a>
Muhammad Awais
źródło
0
<html>
<head>
<script type="text/javascript">
function prepHref(linkElement) {
    var myDiv = document.getElementById('Div_contain_image');
    var myImage = myDiv.children[0];
    linkElement.href = myImage.src;
}
</script>
</head>
<body>
<div id="Div_contain_image"><img src="YourImage.jpg" alt='MyImage'></div>
<a href="#" onclick="prepHref(this)" download>Click here to download image</a>
</body>
</html>
Engr Zardari
źródło
0

Możesz bezpośrednio pobrać ten plik za pomocą tagu kotwicy bez większego kodu.
Skopiuj fragment i wklej w edytorze tekstu i wypróbuj ...!

<html>
<head>
</head>
<body>
   <div>
     <img src="https://upload.wikimedia.org/wikipedia/commons/1/1f/SMirC-thumbsup.svg" width="200" height="200">
      <a href="#" download="https://upload.wikimedia.org/wikipedia/commons/1/1f/SMirC-thumbsup.svg"> Download Image </a>
   </div>
</body>
</html>

vinod
źródło
2
dodaj więcej szczegółów, na przykład gdzie ten kod może być użyty.
Maciej S.
-2

A co z użyciem funkcji .click () i tagu?

(Wersja skompresowana)

<a id="downloadtag" href="examplefolder/testfile.txt" hidden download></a>

<button onclick="document.getElementById('downloadtag').click()">Download</button>

Teraz możesz go uruchomić za pomocą js. Nie otwiera się, jak inne przykłady, plików graficznych i tekstowych!

(wersja z funkcją js)

function download(){
document.getElementById('downloadtag').click();
}
<!-- HTML -->
<button onclick="download()">Download</button>
<a id="downloadtag" href="coolimages/awsome.png" hidden download></a>

Trujący szept
źródło
-5

znalazłem to

<a href="link/to/My_Image_File.jpeg" download>Download Image File</a>

nie działa dla mnie. Nie wiem dlaczego.

Odkryłem, że możesz dołączyć ?download=trueparametr na końcu swojego łącza, aby wymusić pobranie. Myślę, że zauważyłem tę technikę używaną przez Dysk Google.

W swoim łączu umieść ?download=truena końcu swojego href.

Możesz również użyć tej techniki, aby ustawić nazwę pliku w tym samym czasie.

W swoim łączu umieść ?download=true&filename=My_Image_File.jpegna końcu swojego href.

Mufasa
źródło
2
? download = true jest przekazywany do Dysku Google, aby poinformować ich serwer, aby wysłał poprawny nagłówek w celu pobrania obrazu. Nie jest to coś, co działałoby w innym środowisku, gdyby nie zostało specjalnie skonfigurowane w ten sposób.
muncherelli
-15

Nie musisz pisać w tym celu js, po prostu użyj:

<a href="path_to/image.jpg" alt="something">Download image</a>

A sama przeglądarka automatycznie pobierze obraz.

Jeśli z jakiegoś powodu to nie zadziała, dodaj atrybut pobierania. Za pomocą tego atrybutu możesz ustawić nazwę pliku do pobrania:

<a href="path_to/image.jpg" download="myImage">Download image</a>
António Regadas
źródło
Łącze do obrazu otworzy obraz tylko w tym samym oknie, chyba że Twoja przeglądarka jest skonfigurowana inaczej. downloadAtrybut nie jest dostępna we wszystkich przeglądarkach.
Projekt Adrian