Wann ist es sicher, URL.revokeObjectURL aufzurufen?

Lesezeit: 4 Minuten

Benutzer-Avatar
Mann

Wenn ich richtig verstehe URL.createObjectURL erstellt eine URL, die eine Datei oder ein Blob darstellt. Da die URL nur eine Zeichenfolge ist, kann der Browser nicht wissen, wann Sie mit der Ressource, die die URL darstellt, fertig sind, sodass eine bereitgestellt wird URL.revokeObjectURL Funktion.

MDN-Shows dieses Beispiel:

var canvas = document.getElementById("canvas");

canvas.toBlob(function(blob) {
  var newImg = document.createElement("img");
  var url = URL.createObjectURL(blob);

  newImg.onload = function() {
    // no longer need to read the blob so it's revoked
    URL.revokeObjectURL(url);
  };

  newImg.src = url;
  document.body.appendChild(newImg);
});

Also einige Fragen

  1. Wäre es sicher, den Code zu ändern, um die URL sofort nach der Zuweisung zu widerrufen? newImg.src?

    var canvas = document.getElementById("canvas");
    
    canvas.toBlob(function(blob) {
      var newImg = document.createElement("img");
      var url = URL.createObjectURL(blob);
    
      newImg.src = url;
      // no longer need to read the blob as it's assigned to newImg.src
      URL.revokeObjectURL(url);
      document.body.appendChild(newImg);
    });
    

    Ich vermute, die Antwort ist “nein”, weil möglicherweise nichts begonnen hat newImg.src = url;. Es ist zu diesem Zeitpunkt immer noch nur eine Zeichenfolge und wird dies bleiben, bis das aktuelle JavaScript-Ereignis beendet wird. Oder ist es?

  2. Wäre es gültig/legal/korrekt, die URL zu widerrufen, sie aber dennoch zu verwenden, obwohl sie weiß, dass sie von anderen Objekten referenziert wird?

    var canvas = document.getElementById("canvas");
    
    canvas.toBlob(function(blob) {
      var newImg = document.createElement("img");
      var url = URL.createObjectURL(blob);
    
      newImg.onload = function() {
        // no longer need to read the blob so it's revoked
        URL.revokeObjectURL(url);
    
        // Use the URL again even though it's revoked
        var newImg2 = new Image():
        newImg2.src = url; 
      };
    
      newImg.src = url;
      document.body.appendChild(newImg);
    });
    

    In diesem Fall weise ich zu newImg2.src = url obwohl ich die URL bereits widerrufen habe. Die Idee ist das newImg verweist immer noch auf die Blob-URL, sodass es gültig erscheint, dies sagen zu können

    someImage.src = someOtherImage.src
    

    jederzeit. Ist es?

  • 1. Wahrscheinlich nicht, denn diese URL muss es sein hineingeparst ein Bild durch den Browser, und das braucht Zeit. 2. newImg.src ist nicht Ihre „alte“ Blob-URL nicht mehr, es ist nur eine (Daten-)URL wie aus jeder anderen Quelle. Dass das „Original“ widerrufen (und damit der Müllabfuhr übergeben) wurde, hat keinen Einfluss darauf, was Sie hier tun irgendein Weg.

    – CBroe

    2. Februar 2016 um 18:30 Uhr


  • konntest du nicht einfach Prüfung Dies

    – adeneo

    2. Februar 2016 um 18:34 Uhr

Benutzer-Avatar
Mann

Okay, gut, nach dem Rat von @adeneo habe ich das getestet

$('#test').on('change', function(e) {
	var newImg = document.createElement("img");
    var url = URL.createObjectURL( e.target.files[0] )
    console.log(url);
    
    newImg.src = url;
    URL.revokeObjectURL(url);
    document.body.appendChild(newImg);
    console.log(url);
});

$('#test3').on('change', function(e) {
	var newImg = document.createElement("img");
    var url = URL.createObjectURL( e.target.files[0] )
    console.log(url);
    
    newImg.src = url;
    newImg.onload = function() {
    	URL.revokeObjectURL(url);
    	document.body.appendChild(newImg);
      var i = new Image();
      i.src=  newImg.src;
      document.body.appendChild(i);
      setTimeout(function() {
        var g = new Image();
        g.src = newImg.src;
        document.body.appendChild(g);
      }, 3000);
    }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>test revoke before use</p>
<input type="file" id="test"/>
<br />
<br />
<br />
<p>test use revoke use</p>
<input type="file" id="test3" />

Zumindest einmal in Firefox URL.revokeObjectURL aufgerufen wird, kann die URL nicht mehr verwendet werden, obwohl andere Dinge darauf zugreifen.

Also schlagen sowohl #1 als auch #2 in der Frage fehl und obwohl in #2 newImg.src hat immer noch die URL, die URL einmal nirgendwo anders funktionieren wird URL.revokeObjectURL genannt worden.

  • also im Grunde, bis wir ein Bild haben, das das Bild anzeigen muss (über src) – sollten wir nicht “widerrufen” aufrufen?

    – Sergej Rudenko

    7. August 2018 um 20:44 Uhr

  • Ich habe mein Blob widerrufen, nachdem ich es als festgelegt hatte img src, alles war in Ordnung. Ich habe mein Blob widerrufen, nachdem ich es als festgelegt hatte background-image CSS-Eigenschaft, alles war nicht in Ordnung! Es wurde Firefox verwendet.

    – MahanGM

    23. Oktober 2019 um 22:42 Uhr


  • Ich würde erwarten, dass imgs in Ordnung ist, wenn Sie die URL vor dem Widerruf verwenden, aber nicht in Ordnung, wenn Sie versuchen, die URL nach dem Widerruf zu verwenden.

    – Gman

    23. Oktober 2019 um 23:32 Uhr

Benutzer-Avatar
Saar Twito

In React gibt es einen Hook namens useEffect, und eines der Dinge, die er tut, ist, welche Aktion Sie ausführen möchten, bevor Sie die Komponente (Funktion) verlassen, und dort geben Sie die vorhandene Objekt-URL frei, die zuvor war erstellt durch Aufrufen von URL.createObjectURL().

Freigeben einer vorhandenen Objekt-URL mit URL.revokeObjectURL

1

1227950cookie-checkWann ist es sicher, URL.revokeObjectURL aufzurufen?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy