Was ist eine Bild-URL?
Eine Bild-URL ist eine Netzwerkadresse, die eine Bildressource identifiziert und Parameter für Transformation oder Auslieferung enthalten kann. Sie kann auf eine feste Datei verweisen oder auf einen Dienst, der anhand des angefragten Pfads oder der Abfrage eine Antwort erzeugt.
So funktionieren Bild-URLs
Eine Bild-URL erfüllt zwei Aufgaben: Sie benennt eine Ressource und bildet den Hauptbestandteil des Schlüssels, unter dem Browser und CDNs die Antwort speichern. Ein fester Pfad kann auf gespeicherte Bytes verweisen. Ein Transformationsdienst liest die URL dagegen als Verarbeitungsanleitung: imgproxy entnimmt beispielsweise Verarbeitungsoptionen und Quelladresse den Pfadsegmenten und das Ausgabeformat der Dateiendung, während andere Dienste Größe oder Format aus Abfrageparametern übernehmen. Der Client ruft die URL ab, der Server kann anhand von Anfrageheadern wie Accept zwischen Darstellungen wählen, und jeder Cache speichert das Ergebnis unter der URL sowie allen weiteren Bestandteilen, die laut seiner Konfiguration in den Schlüssel eingehen. Dazu gehören etwa Anfrageheader, die die Antwort in Vary nennt. Zwei URLs, die sich nur in einem vom Dienst ignorierten Detail unterscheiden, werden von jedem Cache, der dieses Detail im Schlüssel behält, dennoch separat gespeichert.
Wichtige Fakten
- Bestimmt die Dateiendung das Bildformat? Nein. Ein Dienst kann die Endung als angefordertes Ausgabeformat auswerten, wie imgproxy es tut. Entscheidend ist aber die Antwort: Der Server gibt das Format in
Content-Typean. Für ein Element vom Typimglegt der HTML-Standard fest, dass Browser das Bildformat zusätzlich anhand der ersten Bytes erkennen sollten, wobei der Header den offiziellen Typ angibt. Eine URL mit der Endung.jpgkann daher WebP oder AVIF ausliefern und trotzdem angezeigt werden. Wählt der Server dieses Format anhand des AnfrageheadersAccept, gibt es für eine URL mehrere Antworten: Der Server sollteVary: Acceptsenden, und jedes vorgeschaltete CDN beziehungsweise jeder Caching-Proxy mussAcceptberücksichtigen. Andernfalls kann ein Cache ein gespeichertes WebP- oder AVIF-Bild für einen Browser wiederverwenden, der es nicht angefordert hat. Für manche zwischengeschalteten Systeme ist die Endung durchaus relevant: Das CDN von Cloudflare entscheidet anhand der Dateiendung und nicht anhand des MIME-Typs, was es standardmäßig zwischenspeichert. Eine Bild-URL ohne aufgeführte Endung wird daher standardmäßig nicht zwischengespeichert, sofern keine Cache-Regel dies vorgibt. - Sind zwei URLs mit denselben Parametern in unterschiedlicher Reihenfolge für einen Cache identisch? Nur wenn der Cache den Query-String normalisiert oder ihn aus seinem Schlüssel ausschließt. RFC 3986 vergleicht URIs als Zeichenfolgen, und seine Normalisierungsregeln ändern die Reihenfolge der Query-Parameter nicht. Amazon CloudFront dokumentiert, dass
?color=red&size=largeund?size=large&color=redals zwei Objekte zwischengespeichert werden, wenn das Caching auf Query-Parametern basiert. Auch die Groß- und Kleinschreibung von Parameternamen und Werten zählt dabei. Cloudflare nimmt den vollständigen Query-String in seinen standardmäßigen Cache-Schlüssel auf und führt die Optionen „Query-String sortieren“ und „Query-String ignorieren“ auf. Wer Parameter stets in derselben Reihenfolge und Schreibweise erzeugt, vermeidet doppelte Cache-Einträge und Transformationen. Auch die umgekehrte Richtung ist wichtig: Ein Parameter, der das Bild verändert, muss Teil des Cache-Schlüssels sein. Denn ein Cache, der den Query-String ignoriert, weist URLs, die sich nur in ihren Parametern unterscheiden, denselben Schlüssel zu. - Kann jeder die Parameter einer Transformations-URL ändern? Ja, sofern der Dienst Anfragen ohne gültige Signatur nicht ablehnt oder anderweitig einschränkt, welche Anfragen er annimmt. Signierte URLs zu erzeugen reicht nicht aus, wenn der Dienst weiterhin unsignierte URLs bedient: Bei imgproxy ist die Signaturprüfung standardmäßig ausgeschaltet. Die Dokumentation empfiehlt, sie im Produktivbetrieb zu aktivieren, damit Angreifer nicht durch Anfragen nach vielen verschiedenen Größenänderungen einen Denial-of-Service-Angriff ausführen können. Die Signatur ist ein HMAC über den URL-Pfad. Eine Signatur deckt nur die URL ab: imgproxy weist darauf hin, dass sich Anfrage-Header nicht signieren lassen. Das ist relevant, wenn das Ausgabeformat oder die Breite aus einem Header übernommen wird.
- Warum kann eine Seite ein Bild von einem anderen Ursprung anzeigen, aber dessen Pixel nicht auslesen? Eine Seite kann ein Bild von einem anderen Ursprung normalerweise anzeigen. Wird es jedoch ohne CORS-Freigabe auf einen Canvas gezeichnet, wird dieser als verunreinigt markiert. Danach lösen
getImageData(),toBlob()undtoDataURL()einen Fehler vom TypSecurityErroraus. Das verhindert, dass eine Seite mithilfe von Bildern private Daten aus anderen Websites ausliest. Zum Auslesen der Pixel muss der Bildhost einen Header namensAccess-Control-Allow-Originsenden, der die Seite zulässt. Außerdem benötigt das Elementimgdas Attributcrossorigin(beim Erstellen des Bildes durch ein Skript alscrossOrigingesetzt). Mitcrossoriginsendet der Browser einen Anfrage-Header namensOrigin, den eine einfache ursprungsübergreifende Anfrage überimgnicht enthält. Cloudflare nimmt den Anfrage-HeaderOriginin seinen standardmäßigen Cache-Schlüssel auf. Anfragen für dieselbe URL, die sich in diesem Header unterscheiden, werden dort daher getrennt zwischengespeichert.
Wann Bild-URLs wichtig sind
Der Aufbau einer Bild-URL wird wichtig, wenn das Bild auf Anfrage transformiert oder über ein CDN ausgeliefert wird. Denn die URL bestimmt dann sowohl die erzeugten Bytes als auch die zwischengespeicherte Kopie, die wiederverwendet wird. Legen Sie vor der Veröffentlichung der URLs fest, welche Reihenfolge und Groß- und Kleinschreibung die Parameter haben, ob das Ausgabeformat in der URL angegeben oder anhand des Headers Accept ausgehandelt wird und ob die URL signiert wird. Die Aushandlung ist nur sicher, wenn jeder dem Dienst vorgeschaltete Cache die Formate getrennt hält. Seiten und andere Systeme, die eine URL gespeichert haben, fragen weiterhin genau diese Form an.
So hilft Transloadit bei Bild-URLs
Eine Bild-URL aus dem Smart CDN von Transloadit ist eine solche Transformations-URL. Der Workspace-Name ist die Subdomain von tlcdn.com. Der Pfad enthält den Template-Namen und den Pfad der Quelldatei. Query-Parameter wie w=730 erreichen das Template als Assembly Variables wie ${fields.w}. Das Template bestimmt also, welche Parameter überhaupt eine Wirkung haben. Die URL lässt sich mit einer Ablaufzeit (exp) und einer Signatur (sig) signieren. Die Signatur muss in Ihrem Backend erzeugt werden, da sie das Auth Secret verwendet. Werden eine signierte URL oder ihre Parameter nachträglich geändert, stimmt die Signatur nicht mehr überein. Das hindert Außenstehende nur dann daran, die URL oder ihre Parameter zu verändern, wenn unsignierte Anfragen abgelehnt werden. Die verlinkten Seiten beschreiben nicht, wie eine unsignierte Anfrage an dasselbe Template behandelt wird. Testen Sie dies daher in Ihrem eigenen Workspace, bevor Sie sich auf die Signierung verlassen.
Das Signierungsverfahren sortiert die Query-Parameter, bevor die Signatur berechnet wird. Die verlinkten Seiten geben nicht an, ob zwei URLs, deren Parameter sich nur in der Reihenfolge unterscheiden, dasselbe zwischengespeicherte Ergebnis nutzen. Erzeugen Sie die Parameter daher in einer festen Reihenfolge.
Quellen
- RFC 3986: allgemeine URI-Syntax, Abschnitt 6 (Normalisierung und Vergleich)
- RFC 9110: HTTP-Semantik, Abschnitte 8.3 (Content-Type) und 12.5.5 (Vary)
- RFC 9111: HTTP-Caching, Abschnitte 2 und 4.1 (Cache-Schlüssel und Vary)
- HTML-Standard: Bilder einschließlich der Regeln zur Erkennung von Bildformaten
- WHATWG MIME Sniffing Standard: Formaterkennung im Bildkontext
- HTML-Standard: das canvas-Element und das origin-clean-Flag
- MDN: Bilder von anderen Ursprüngen in einem Canvas verwenden
- MDN: das Attribut crossorigin
- MDN: der Anfrage-Header Origin
- Amazon CloudFront: Inhalte anhand von Query-Parametern zwischenspeichern
- Cloudflare: Cache-Schlüssel
- Cloudflare: standardmäßiges Cache-Verhalten und standardmäßig zwischengespeicherte Dateiendungen
- imgproxy: URL-Format für die Verarbeitung
- imgproxy: eine URL signieren
- imgproxy: Konfigurationsoptionen, Formaterkennung und Caching