Datei-Upload-Felder
Ein Dateifeld ist eine gewöhnliche string-Eigenschaft mit einem storage-Block. Die
Spalte enthält Text – den Schlüssel (Key) des Objekts im Bucket oder dessen URL, falls
gewünscht – und der Block gibt an, wohin die Bytes übertragen werden und was das Formular akzeptiert.
Diese Trennung ist wichtiger, als es scheint. Der Großteil von storage wird vom Uploader
des Admin-Panels auf dem Weg zur API gelesen, sodass ein Schreibvorgang, der nicht von einem
Formular stammt, diesen nicht durchläuft – diese Optionen tragen den unten stehenden Hinweis. Die beiden
Optionen, die bestimmen, was eine Datei sein darf – maxSize und acceptedFiles –, sind die Ausnahme:
Der Server prüft sie bei jedem Upload in den storagePath der Eigenschaft.
Eine Datei
Abschnitt betitelt „Eine Datei“avatar: { type: "string", name: "Main image", storage: { storagePath: "avatars", acceptedFiles: ["image/*"], maxSize: 2 * 1024 * 1024 }}Mehrere Dateien
Abschnitt betitelt „Mehrere Dateien“Ein Array desselben Typs. Der storage-Block wandert in of, da er
jedes einzelne Element und nicht die Liste beschreibt:
images: { type: "array", name: "Images", of: { type: "string", storage: { storagePath: "images", acceptedFiles: ["image/*"] } }}Storage-Optionen
Abschnitt betitelt „Storage-Optionen“Alles innerhalb von storage.
| Eigenschaft | Typ | Beschreibung |
|---|---|---|
storagePath |
string | function |
Erforderlich. Wohin im Bucket die Datei gespeichert wird. Ein String mit Platzhaltern – {file}, {file.name}, {file.ext}, {rand}, {entityId}, {propertyKey}, {path} – oder eine Funktion des Upload-Kontexts. Nur im Admin-Formular – wird nicht von der API oder der Datenbank erzwungen: Der Uploader des Panels löst dies auf, und client.storage.upload() vergibt einen eigenen Schlüssel. Ein als String angegebener Pfad ist zugleich der Ort, an dem der Server jeden Upload an das maxSize- und acceptedFiles-Limit dieser Eigenschaft bindet. |
fileName |
string | function |
Der Dateiname des hochgeladenen Objekts mit denselben Platzhaltern. Nur im Admin-Formular – wird nicht von der API oder der Datenbank erzwungen. |
storageSource |
string |
Welcher registrierte Bucket verwendet werden soll, wenn ein Projekt mehr als einen hat. Das bucket("media")-Handle funktioniert hier ebenfalls. |
public |
boolean |
Unter dem öffentlichen Präfix speichern und über eine stabile, tokenlose, cachebare URL bereitstellen. Standardmäßig false, was private Objekte und kurzlebige signierte URLs bedeutet. |
acceptedFiles |
FileType[] |
MIME-Typen, die diese Eigenschaft akzeptiert. Die Sternchen-Form funktioniert – image/*. Wird vom Server erzwungen für jeden Upload in den storagePath der Eigenschaft — siehe Was der Server prüft. |
maxSize |
number |
Größte akzeptierte Datei in Bytes. Wird vom Server erzwungen, ebenso wie acceptedFiles, sowohl bei normalen als auch bei fortsetzbaren (resumable) Upload-Pfaden. |
metadata |
Record<string, unknown> |
Objekt-Metadaten, die zusammen mit der Datei gespeichert werden sollen. |
includeBucketUrl |
boolean |
Schreibt s3://my-bucket/path/to/file.png in die Spalte anstelle von path/to/file.png. Standardmäßig false. |
storeUrl |
boolean |
Schreibt die Download-URL in die Spalte anstelle des Keys. Standardmäßig false, und es empfiehlt sich, dies so zu belassen: Eine URL, die ein Token enthält, funktioniert nicht mehr, sobald das Token abläuft, womit die ursprüngliche Referenz verloren ist. |
imageResize |
ImageResize |
Vor dem Hochladen skalieren und zuschneiden, für image/jpeg, image/png und image/webp. Nur im Admin-Formular – wird nicht von der API oder der Datenbank erzwungen. |
processFile |
(file: File) => Promise<File> |
Transformiert die Datei vor dem Hochladen. Läuft im Browser. Nur im Admin-Formular – wird nicht von der API oder der Datenbank erzwungen. |
postProcess |
(pathOrUrl: string) => Promise<string> |
Transformiert den aufgelösten Pfad oder die URL vor dem Speichern. Läuft im Browser. Nur im Admin-Formular – wird nicht von der API oder der Datenbank erzwungen. |
previewUrl |
(fileName: string) => string |
Erstellt die Vorschau-URL für Fälle, in denen die tatsächliche Adresse der Datei nicht der Wert des Feldes ist. Nur im Admin-Formular – wird nicht von der API oder der Datenbank erzwungen. |
Bildgrößenanpassung
Abschnitt betitelt „Bildgrößenanpassung“imageResize akzeptiert maxWidth und maxHeight in Pixeln, einen mode von
"contain" (herunterskalieren zum Einpassen, Standard) oder "cover" (Bereich ausfüllen
und beschneiden), ein format von "original", "jpeg", "png" oder "webp" sowie
eine quality zwischen 0 und 100 für verlustbehaftete Formate – standardmäßig 80. Dies geschieht
im Browser, bevor die Bytes gesendet werden; ein Upload, der nicht über das Panel
erfolgt ist, wird daher in seiner Originalgröße gespeichert.
Was der Server prüft
Abschnitt betitelt „Was der Server prüft“maxSize und acceptedFiles wurden früher von genau einer Stelle erzwungen: dem
Browser. Die Upload-Route kannte lediglich eine globale Größenbeschränkung und wusste
nichts über die Eigenschaft, für die eine Datei bestimmt war. Ein curl -F file=@payload.exe
am Dateiauswahldialog vorbei platzierte somit eine 40-MB-Binärdatei im Avatar-Bucket, und die
Konfiguration, die etwas anderes vorgab, wurde nie abgefragt.
Beide werden nun vom Server anhand des Orts, an dem die Datei landet, geprüft. Auf
0.23 werden sie nur anhand der Eigenschaft geprüft, die ein Upload benennt, und ein Upload, der
keine benennt, erfüllt allein das eigene Limit der Quelle. Der storagePath
einer Eigenschaft ist dort, wohin ihre Dateien gehen, also ist es auch dort, wo ihre Limits greifen:
Jeder Upload, dessen Schlüssel eine Datei direkt unter diesem Pfad ist – aus dem Panel,
client.storage.putObject, einem fortsetzbaren Upload, Studios Storage-Browser oder curl –
erfüllt sie, unabhängig davon, ob er die Eigenschaft benennt, auf der eigenen Storage-Quelle der
Eigenschaft. Platzhalter entsprechen dem, was das Panel einsetzen würde: {entityId}, {rand},
{file} und Ähnliches stehen für ein einzelnes Pfadsegment, {path} für eine beliebige Anzahl. Der
Pfad einer Eigenschaft mit public: true liegt unter public/.
- Mehrere Eigenschaften, die sich einen Pfad teilen: Eine Datei, die eine von ihnen akzeptiert, wird akzeptiert.
- Ein Upload, der zusätzlich seine Eigenschaft benennt (
collection+property, so wieputObject({ context })sie sendet), wird auch an diese Eigenschaft gebunden. Eine lockerere Eigenschaft zu benennen, schaltet den Pfad einer strengeren nicht frei. Die Uploads des Panels (Dateifelder, Tabellenzellen und Markdown-Bilder) benennen sie immer. - Ein als Funktion geschriebener
storagePathkann nicht gelesen werden, ohne ihn auszuführen, daher gibt es für ihn keine serverseitige Regel: Diese Limits greifen nur für Uploads, die die Eigenschaft benennen, was die des Panels tun. - Ein Pfad, den keine Eigenschaft beansprucht, unterliegt allein dem eigenen Limit der Quelle
(
STORAGE_MAX_FILE_SIZE).
Bilder in einem Markdown-Feld
Abschnitt betitelt „Bilder in einem Markdown-Feld“Eine Markdown-Eigenschaft (admin.markdown: true) mit einem storage-Block nimmt in ihrem Editor
Bild-Uploads an. Der Text speichert jedes Bild als Storage-Referenz —
 — nicht als URL: Die URL einer privaten Datei trägt ein
Download-Token, das innerhalb von Minuten abläuft, während der Text gespeichert bleibt. Der Editor
und die Vorschauen des Admin-Panels tauschen jede Referenz beim Anzeigen gegen eine frische URL
aus; eine Website, die das Feld rendert, tut dasselbe mit resolveStorageReferences(text, client)
— siehe Dateien innerhalb von Text.
Text, der vor den Referenzen gespeichert wurde, enthält die Download-URLs selbst, mit abgelaufenen
Tokens. Der Editor, die Vorschauen und resolveStorageReferences erneuern sie, wenn sie den Text
anzeigen, denn ein Token nennt weiterhin sein Objekt; das erneute Einfügen des Bildes oder das
Umschreiben des Textes mit storageReferencesForDownloadUrls(text) speichert eine Referenz.
Wohin die Datei gespeichert werden darf
Abschnitt betitelt „Wohin die Datei gespeichert werden darf“storagePath ist ein Standardwert, keine feste Begrenzung: Nichts auf dem Server beschränkt
einen Upload auf dieses Präfix. Zu entscheiden, wer wohin schreiben darf, ist Aufgabe von
Storage-Autorisierungsregeln – siehe Storage.
Dateien werden nie automatisch gelöscht
Abschnitt betitelt „Dateien werden nie automatisch gelöscht“Ein Dateifeld zu leeren, seine Datei zu ersetzen oder die Zeile zu löschen, zu der es gehört, lässt
das gespeicherte Objekt unangetastet. Jeder Upload erhält einen eigenen Schlüssel, sodass ein Ersatz
ein neues Objekt schreibt, statt das alte zu überschreiben, und nichts entfernt das vorherige: Zwei
Zeilen können denselben Schlüssel halten, daher kann das Panel nicht wissen, dass eine Datei ungenutzt
ist. Objekte, auf die keine Zeile mehr verweist, bleiben im Bucket – und werden weiterhin abgerechnet
–, bis Sie sie löschen: über Studios Storage-Browser, mit client.storage.deleteObject(key) oder mit
einer Lifecycle-Regel auf dem Bucket. Seit 0.25 rebase storage orphans listet die Dateien auf, die keine Zeile nennt, und löscht sie
mit --delete — siehe die CLI.
Eine Eigenschaft zu einer anderen Storage-Quelle verschieben
Abschnitt betitelt „Eine Eigenschaft zu einer anderen Storage-Quelle verschieben“Ein Dateifeld speichert den Schlüssel des Objekts, nicht dessen Quelle. Die storageSource einer
Eigenschaft zu ändern, lässt jeden vorhandenen Wert auf die neue Quelle zeigen, in der diese
Schlüssel nicht existieren, sodass Vorschauen von Dateien, die vor der Änderung hochgeladen wurden,
mit „nicht gefunden“ antworten. Kopieren Sie die Objekte unter denselben Schlüsseln in die neue
Quelle, bevor Sie die Eigenschaft ändern — mit rebase storage move --from <old> --to <new> --prefix <storagePath> oder dem eigenen Werkzeug des Anbieters, etwa
aws s3 sync oder gcloud storage cp — oder behalten Sie die alte Quelle für die bestehenden
Dateien.
Nächste Schritte
Abschnitt betitelt „Nächste Schritte“- Properties – alle Eigenschaftstypen und ihre Optionen
- Storage – Buckets, signierte URLs und wie der Server mit Uploads verfährt
- Security Rules (RLS) – wer die Zeilen lesen darf, mit denen diese Dateien verknüpft sind