supabase-storage
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseSupabase Storage Operations
Supabase Storage 操作
Overview
概述
This skill provides file storage operations through the Supabase Storage API. Supports bucket management, file uploads/downloads, listing files, generating URLs, and managing access control.
本技能通过Supabase Storage API提供文件存储操作,支持存储桶管理、文件上传/下载、文件列出、URL生成以及访问控制管理。
Prerequisites
前提条件
Required environment variables:
bash
export SUPABASE_URL="https://your-project.supabase.co"
export SUPABASE_KEY="your-anon-or-service-role-key"Helper script:
This skill uses the shared Supabase API helper. Make sure to source it:
bash
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"所需环境变量:
bash
export SUPABASE_URL="https://your-project.supabase.co"
export SUPABASE_KEY="your-anon-or-service-role-key"辅助脚本:
本技能使用共享的Supabase API辅助脚本,请确保已加载它:
bash
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"Bucket Operations
存储桶操作
List Buckets
列出存储桶
Get all storage buckets:
bash
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"
supabase_get "/storage/v1/bucket"获取所有存储桶:
bash
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"
supabase_get "/storage/v1/bucket"Create Bucket
创建存储桶
Create a new storage bucket:
bash
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"创建新的存储桶:
bash
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"Public bucket
公共存储桶
supabase_post "/storage/v1/bucket" '{
"name": "avatars",
"public": true
}'
supabase_post "/storage/v1/bucket" '{
"name": "avatars",
"public": true
}'
Private bucket
私有存储桶
supabase_post "/storage/v1/bucket" '{
"name": "private-documents",
"public": false,
"file_size_limit": 52428800,
"allowed_mime_types": ["image/png", "image/jpeg", "application/pdf"]
}'
undefinedsupabase_post "/storage/v1/bucket" '{
"name": "private-documents",
"public": false,
"file_size_limit": 52428800,
"allowed_mime_types": ["image/png", "image/jpeg", "application/pdf"]
}'
undefinedGet Bucket Details
获取存储桶详情
Retrieve bucket information:
bash
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"
supabase_get "/storage/v1/bucket/avatars"检索存储桶信息:
bash
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"
supabase_get "/storage/v1/bucket/avatars"Update Bucket
更新存储桶
Update bucket settings:
bash
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"
curl -s -X PUT \
"${SUPABASE_URL}/storage/v1/bucket/avatars" \
-H "apikey: ${SUPABASE_KEY}" \
-H "Authorization: Bearer ${SUPABASE_KEY}" \
-H "Content-Type: application/json" \
-d '{
"public": false,
"file_size_limit": 10485760
}'更新存储桶设置:
bash
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"
curl -s -X PUT \
"${SUPABASE_URL}/storage/v1/bucket/avatars" \
-H "apikey: ${SUPABASE_KEY}" \
-H "Authorization: Bearer ${SUPABASE_KEY}" \
-H "Content-Type: application/json" \
-d '{
"public": false,
"file_size_limit": 10485760
}'Delete Bucket
删除存储桶
Delete a bucket (must be empty):
bash
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"
supabase_delete "/storage/v1/bucket/old-bucket"删除存储桶(必须为空):
bash
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"
supabase_delete "/storage/v1/bucket/old-bucket"Empty Bucket
清空存储桶
Delete all files in a bucket:
bash
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"
supabase_post "/storage/v1/bucket/avatars/empty" '{}'删除存储桶中的所有文件:
bash
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"
supabase_post "/storage/v1/bucket/avatars/empty" '{}'File Operations
文件操作
Upload File
上传文件
Upload a file to storage:
bash
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"
BUCKET_NAME="avatars"
FILE_PATH="/path/to/local/image.jpg"
STORAGE_PATH="user-123/profile.jpg"
curl -s -X POST \
"${SUPABASE_URL}/storage/v1/object/${BUCKET_NAME}/${STORAGE_PATH}" \
-H "apikey: ${SUPABASE_KEY}" \
-H "Authorization: Bearer ${SUPABASE_KEY}" \
-F "file=@${FILE_PATH}"Upload with upsert (overwrite if exists):
bash
curl -s -X POST \
"${SUPABASE_URL}/storage/v1/object/${BUCKET_NAME}/${STORAGE_PATH}" \
-H "apikey: ${SUPABASE_KEY}" \
-H "Authorization: Bearer ${SUPABASE_KEY}" \
-H "x-upsert: true" \
-F "file=@${FILE_PATH}"Upload with content type:
bash
curl -s -X POST \
"${SUPABASE_URL}/storage/v1/object/${BUCKET_NAME}/${STORAGE_PATH}" \
-H "apikey: ${SUPABASE_KEY}" \
-H "Authorization: Bearer ${SUPABASE_KEY}" \
-H "Content-Type: image/jpeg" \
-F "file=@${FILE_PATH}"将文件上传到存储服务:
bash
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"
BUCKET_NAME="avatars"
FILE_PATH="/path/to/local/image.jpg"
STORAGE_PATH="user-123/profile.jpg"
curl -s -X POST \
"${SUPABASE_URL}/storage/v1/object/${BUCKET_NAME}/${STORAGE_PATH}" \
-H "apikey: ${SUPABASE_KEY}" \
-H "Authorization: Bearer ${SUPABASE_KEY}" \
-F "file=@${FILE_PATH}"覆盖式上传(若文件已存在则覆盖):
bash
curl -s -X POST \
"${SUPABASE_URL}/storage/v1/object/${BUCKET_NAME}/${STORAGE_PATH}" \
-H "apikey: ${SUPABASE_KEY}" \
-H "Authorization: Bearer ${SUPABASE_KEY}" \
-H "x-upsert: true" \
-F "file=@${FILE_PATH}"指定内容类型上传:
bash
curl -s -X POST \
"${SUPABASE_URL}/storage/v1/object/${BUCKET_NAME}/${STORAGE_PATH}" \
-H "apikey: ${SUPABASE_KEY}" \
-H "Authorization: Bearer ${SUPABASE_KEY}" \
-H "Content-Type: image/jpeg" \
-F "file=@${FILE_PATH}"Download File
下载文件
Download a file from storage:
bash
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"
BUCKET_NAME="avatars"
STORAGE_PATH="user-123/profile.jpg"
OUTPUT_FILE="/path/to/save/downloaded.jpg"
curl -s -X GET \
"${SUPABASE_URL}/storage/v1/object/${BUCKET_NAME}/${STORAGE_PATH}" \
-H "apikey: ${SUPABASE_KEY}" \
-H "Authorization: Bearer ${SUPABASE_KEY}" \
-o "${OUTPUT_FILE}"Download to stdout (pipe to other commands):
bash
curl -s -X GET \
"${SUPABASE_URL}/storage/v1/object/${BUCKET_NAME}/${STORAGE_PATH}" \
-H "apikey: ${SUPABASE_KEY}" \
-H "Authorization: Bearer ${SUPABASE_KEY}"从存储服务下载文件:
bash
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"
BUCKET_NAME="avatars"
STORAGE_PATH="user-123/profile.jpg"
OUTPUT_FILE="/path/to/save/downloaded.jpg"
curl -s -X GET \
"${SUPABASE_URL}/storage/v1/object/${BUCKET_NAME}/${STORAGE_PATH}" \
-H "apikey: ${SUPABASE_KEY}" \
-H "Authorization: Bearer ${SUPABASE_KEY}" \
-o "${OUTPUT_FILE}"下载到标准输出(可通过管道传递给其他命令):
bash
curl -s -X GET \
"${SUPABASE_URL}/storage/v1/object/${BUCKET_NAME}/${STORAGE_PATH}" \
-H "apikey: ${SUPABASE_KEY}" \
-H "Authorization: Bearer ${SUPABASE_KEY}"List Files
列出文件
List files in a bucket:
bash
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"
BUCKET_NAME="avatars"
supabase_post "/storage/v1/object/list/${BUCKET_NAME}" '{
"limit": 100,
"offset": 0,
"sortBy": {
"column": "name",
"order": "asc"
}
}'List files in a specific folder:
bash
supabase_post "/storage/v1/object/list/${BUCKET_NAME}" '{
"prefix": "user-123/",
"limit": 100
}'Search files:
bash
supabase_post "/storage/v1/object/list/${BUCKET_NAME}" '{
"search": "profile",
"limit": 50
}'列出存储桶中的文件:
bash
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"
BUCKET_NAME="avatars"
supabase_post "/storage/v1/object/list/${BUCKET_NAME}" '{
"limit": 100,
"offset": 0,
"sortBy": {
"column": "name",
"order": "asc"
}
}'列出指定文件夹中的文件:
bash
supabase_post "/storage/v1/object/list/${BUCKET_NAME}" '{
"prefix": "user-123/",
"limit": 100
}'搜索文件:
bash
supabase_post "/storage/v1/object/list/${BUCKET_NAME}" '{
"search": "profile",
"limit": 50
}'Delete File
删除文件
Delete a single file:
bash
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"
BUCKET_NAME="avatars"
STORAGE_PATH="user-123/old-profile.jpg"
supabase_delete "/storage/v1/object/${BUCKET_NAME}/${STORAGE_PATH}"Delete multiple files:
bash
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"
BUCKET_NAME="avatars"
supabase_delete "/storage/v1/object/${BUCKET_NAME}" -d '{
"prefixes": ["user-123/temp/", "user-456/draft/"]
}'删除单个文件:
bash
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"
BUCKET_NAME="avatars"
STORAGE_PATH="user-123/old-profile.jpg"
supabase_delete "/storage/v1/object/${BUCKET_NAME}/${STORAGE_PATH}"删除多个文件:
bash
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"
BUCKET_NAME="avatars"
supabase_delete "/storage/v1/object/${BUCKET_NAME}" -d '{
"prefixes": ["user-123/temp/", "user-456/draft/"]
}'Move/Rename File
移动/重命名文件
Move or rename a file:
bash
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"
BUCKET_NAME="avatars"
FROM_PATH="user-123/temp.jpg"
TO_PATH="user-123/final.jpg"
supabase_post "/storage/v1/object/move" '{
"bucketId": "'"${BUCKET_NAME}"'",
"sourceKey": "'"${FROM_PATH}"'",
"destinationKey": "'"${TO_PATH}"'"
}'移动或重命名文件:
bash
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"
BUCKET_NAME="avatars"
FROM_PATH="user-123/temp.jpg"
TO_PATH="user-123/final.jpg"
supabase_post "/storage/v1/object/move" '{
"bucketId": "'"${BUCKET_NAME}"'",
"sourceKey": "'"${FROM_PATH}"'",
"destinationKey": "'"${TO_PATH}"'"
}'Copy File
复制文件
Copy a file to another location:
bash
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"
BUCKET_NAME="avatars"
SOURCE_PATH="user-123/profile.jpg"
DEST_PATH="user-123/profile-backup.jpg"
supabase_post "/storage/v1/object/copy" '{
"bucketId": "'"${BUCKET_NAME}"'",
"sourceKey": "'"${SOURCE_PATH}"'",
"destinationKey": "'"${DEST_PATH}"'"
}'将文件复制到其他位置:
bash
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"
BUCKET_NAME="avatars"
SOURCE_PATH="user-123/profile.jpg"
DEST_PATH="user-123/profile-backup.jpg"
supabase_post "/storage/v1/object/copy" '{
"bucketId": "'"${BUCKET_NAME}"'",
"sourceKey": "'"${SOURCE_PATH}"'",
"destinationKey": "'"${DEST_PATH}"'"
}'URL Generation
URL生成
Get Public URL
获取公共URL
Get public URL for a file (public buckets only):
bash
BUCKET_NAME="avatars"
STORAGE_PATH="user-123/profile.jpg"
PUBLIC_URL="${SUPABASE_URL}/storage/v1/object/public/${BUCKET_NAME}/${STORAGE_PATH}"
echo "Public URL: $PUBLIC_URL"获取文件的公共URL(仅适用于公共存储桶):
bash
BUCKET_NAME="avatars"
STORAGE_PATH="user-123/profile.jpg"
PUBLIC_URL="${SUPABASE_URL}/storage/v1/object/public/${BUCKET_NAME}/${STORAGE_PATH}"
echo "Public URL: $PUBLIC_URL"Create Signed URL
创建签名URL
Generate a signed URL for temporary access:
bash
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"
BUCKET_NAME="private-documents"
STORAGE_PATH="user-123/secret.pdf"
EXPIRES_IN=3600 # 1 hour in seconds
supabase_post "/storage/v1/object/sign/${BUCKET_NAME}/${STORAGE_PATH}" '{
"expiresIn": '"${EXPIRES_IN}"'
}'Response will include:
json
{
"signedURL": "/storage/v1/object/sign/private-documents/user-123/secret.pdf?token=..."
}Full URL:
bash
signed_path=$(supabase_post "/storage/v1/object/sign/${BUCKET_NAME}/${STORAGE_PATH}" '{"expiresIn": 3600}' | jq -r '.signedURL')
full_url="${SUPABASE_URL}${signed_path}"
echo "Signed URL: $full_url"生成用于临时访问的签名URL:
bash
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"
BUCKET_NAME="private-documents"
STORAGE_PATH="user-123/secret.pdf"
EXPIRES_IN=3600 # 1小时,单位为秒
supabase_post "/storage/v1/object/sign/${BUCKET_NAME}/${STORAGE_PATH}" '{
"expiresIn": '"${EXPIRES_IN}"'
}'响应将包含:
json
{
"signedURL": "/storage/v1/object/sign/private-documents/user-123/secret.pdf?token=..."
}完整URL:
bash
signed_path=$(supabase_post "/storage/v1/object/sign/${BUCKET_NAME}/${STORAGE_PATH}" '{"expiresIn": 3600}' | jq -r '.signedURL')
full_url="${SUPABASE_URL}${signed_path}"
echo "Signed URL: $full_url"Create Multiple Signed URLs
批量创建签名URL
Generate signed URLs for multiple files:
bash
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"
BUCKET_NAME="private-documents"
supabase_post "/storage/v1/object/sign/${BUCKET_NAME}" '{
"paths": ["doc1.pdf", "doc2.pdf", "folder/doc3.pdf"],
"expiresIn": 3600
}'为多个文件生成签名URL:
bash
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"
BUCKET_NAME="private-documents"
supabase_post "/storage/v1/object/sign/${BUCKET_NAME}" '{
"paths": ["doc1.pdf", "doc2.pdf", "folder/doc3.pdf"],
"expiresIn": 3600
}'Common Patterns
常见使用模式
Upload with Progress
带进度条的上传
bash
#!/bin/bash
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"
BUCKET_NAME="uploads"
FILE_PATH="/path/to/large-file.zip"
STORAGE_PATH="user-123/backup.zip"
echo "Uploading ${FILE_PATH}..."
curl -X POST \
"${SUPABASE_URL}/storage/v1/object/${BUCKET_NAME}/${STORAGE_PATH}" \
-H "apikey: ${SUPABASE_KEY}" \
-H "Authorization: Bearer ${SUPABASE_KEY}" \
-F "file=@${FILE_PATH}" \
--progress-bar -o /dev/null
if [[ $? -eq 0 ]]; then
echo "Upload successful!"
else
echo "Upload failed!"
exit 1
fibash
#!/bin/bash
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"
BUCKET_NAME="uploads"
FILE_PATH="/path/to/large-file.zip"
STORAGE_PATH="user-123/backup.zip"
echo "正在上传 ${FILE_PATH}..."
curl -X POST \
"${SUPABASE_URL}/storage/v1/object/${BUCKET_NAME}/${STORAGE_PATH}" \
-H "apikey: ${SUPABASE_KEY}" \
-H "Authorization: Bearer ${SUPABASE_KEY}" \
-F "file=@${FILE_PATH}" \
--progress-bar -o /dev/null
if [[ $? -eq 0 ]]; then
echo "上传成功!"
else
echo "上传失败!"
exit 1
fiCheck if File Exists
检查文件是否存在
bash
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"
BUCKET_NAME="avatars"
STORAGE_PATH="user-123/profile.jpg"bash
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"
BUCKET_NAME="avatars"
STORAGE_PATH="user-123/profile.jpg"Try to get file info
尝试获取文件信息
response=$(curl -s -X GET
"${SUPABASE_URL}/storage/v1/object/info/${BUCKET_NAME}/${STORAGE_PATH}"
-H "apikey: ${SUPABASE_KEY}"
-H "Authorization: Bearer ${SUPABASE_KEY}"
-w "\n%{http_code}")
"${SUPABASE_URL}/storage/v1/object/info/${BUCKET_NAME}/${STORAGE_PATH}"
-H "apikey: ${SUPABASE_KEY}"
-H "Authorization: Bearer ${SUPABASE_KEY}"
-w "\n%{http_code}")
http_code=$(echo "$response" | tail -n1)
if [[ $http_code -eq 200 ]]; then
echo "File exists"
else
echo "File does not exist"
fi
undefinedresponse=$(curl -s -X GET
"${SUPABASE_URL}/storage/v1/object/info/${BUCKET_NAME}/${STORAGE_PATH}"
-H "apikey: ${SUPABASE_KEY}"
-H "Authorization: Bearer ${SUPABASE_KEY}"
-w "\n%{http_code}")
"${SUPABASE_URL}/storage/v1/object/info/${BUCKET_NAME}/${STORAGE_PATH}"
-H "apikey: ${SUPABASE_KEY}"
-H "Authorization: Bearer ${SUPABASE_KEY}"
-w "\n%{http_code}")
http_code=$(echo "$response" | tail -n1)
if [[ $http_code -eq 200 ]]; then
echo "文件存在"
else
echo "文件不存在"
fi
undefinedBatch Upload Files
批量上传文件
bash
#!/bin/bash
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"
BUCKET_NAME="uploads"
LOCAL_DIR="/path/to/files"
for file in "$LOCAL_DIR"/*; do
filename=$(basename "$file")
echo "Uploading $filename..."
curl -s -X POST \
"${SUPABASE_URL}/storage/v1/object/${BUCKET_NAME}/batch/${filename}" \
-H "apikey: ${SUPABASE_KEY}" \
-H "Authorization: Bearer ${SUPABASE_KEY}" \
-F "file=@${file}"
echo "✓ Uploaded $filename"
donebash
#!/bin/bash
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"
BUCKET_NAME="uploads"
LOCAL_DIR="/path/to/files"
for file in "$LOCAL_DIR"/*; do
filename=$(basename "$file")
echo "正在上传 $filename..."
curl -s -X POST \
"${SUPABASE_URL}/storage/v1/object/${BUCKET_NAME}/batch/${filename}" \
-H "apikey: ${SUPABASE_KEY}" \
-H "Authorization: Bearer ${SUPABASE_KEY}" \
-F "file=@${file}"
echo "✓ 已上传 $filename"
doneDownload All Files from Bucket
下载存储桶中的所有文件
bash
#!/bin/bash
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"
BUCKET_NAME="avatars"
OUTPUT_DIR="/path/to/download"
mkdir -p "$OUTPUT_DIR"bash
#!/bin/bash
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"
BUCKET_NAME="avatars"
OUTPUT_DIR="/path/to/download"
mkdir -p "$OUTPUT_DIR"Get file list
获取文件列表
files=$(supabase_post "/storage/v1/object/list/${BUCKET_NAME}" '{"limit": 1000}')
files=$(supabase_post "/storage/v1/object/list/${BUCKET_NAME}" '{"limit": 1000}')
Download each file
下载每个文件
echo "$files" | jq -r '.[].name' | while read -r filename; do
echo "Downloading $filename..."
curl -s -X GET \
"${SUPABASE_URL}/storage/v1/object/${BUCKET_NAME}/${filename}" \
-H "apikey: ${SUPABASE_KEY}" \
-H "Authorization: Bearer ${SUPABASE_KEY}" \
-o "${OUTPUT_DIR}/${filename}"
echo "✓ Downloaded $filename"done
undefinedecho "$files" | jq -r '.[].name' | while read -r filename; do
echo "正在下载 $filename..."
curl -s -X GET \
"${SUPABASE_URL}/storage/v1/object/${BUCKET_NAME}/${filename}" \
-H "apikey: ${SUPABASE_KEY}" \
-H "Authorization: Bearer ${SUPABASE_KEY}" \
-o "${OUTPUT_DIR}/${filename}"
echo "✓ 已下载 $filename"done
undefinedImage Transformations
图片转换
Transform images on-the-fly (public buckets):
bash
BUCKET_NAME="avatars"
STORAGE_PATH="user-123/profile.jpg"动态转换图片(仅适用于公共存储桶):
bash
BUCKET_NAME="avatars"
STORAGE_PATH="user-123/profile.jpg"Resize to width 200px
调整宽度为200px
TRANSFORMED_URL="${SUPABASE_URL}/storage/v1/render/image/public/${BUCKET_NAME}/${STORAGE_PATH}?width=200"
TRANSFORMED_URL="${SUPABASE_URL}/storage/v1/render/image/public/${BUCKET_NAME}/${STORAGE_PATH}?width=200"
Resize with quality
调整尺寸并指定质量
TRANSFORMED_URL="${SUPABASE_URL}/storage/v1/render/image/public/${BUCKET_NAME}/${STORAGE_PATH}?width=200&quality=80"
TRANSFORMED_URL="${SUPABASE_URL}/storage/v1/render/image/public/${BUCKET_NAME}/${STORAGE_PATH}?width=200&quality=80"
Multiple transformations
多参数转换
TRANSFORMED_URL="${SUPABASE_URL}/storage/v1/render/image/public/${BUCKET_NAME}/${STORAGE_PATH}?width=300&height=300&resize=contain"
undefinedTRANSFORMED_URL="${SUPABASE_URL}/storage/v1/render/image/public/${BUCKET_NAME}/${STORAGE_PATH}?width=300&height=300&resize=contain"
undefinedAccess Control
访问控制
Storage access is controlled by Storage Policies (RLS) in your Supabase dashboard.
Common policy examples:
Public read, authenticated write:
sql
-- Set in Supabase Dashboard > Storage > Policies
-- Allow public to read
SELECT: true for all users
-- Allow authenticated users to upload their own files
INSERT: auth.uid() = (storage.foldername(name))[1]User-specific folders:
sql
-- Users can only access files in their own folder
SELECT: auth.uid() = (storage.foldername(name))[1]
UPDATE: auth.uid() = (storage.foldername(name))[1]
DELETE: auth.uid() = (storage.foldername(name))[1]存储服务的访问权限由Supabase控制台中的存储策略(RLS)控制。
常见策略示例:
公共读取,认证用户可写入:
sql
-- 在Supabase控制台 > 存储 > 策略中设置
-- 允许所有用户读取
SELECT: true for all users
-- 允许认证用户上传自己的文件
INSERT: auth.uid() = (storage.foldername(name))[1]用户专属文件夹:
sql
-- 用户仅能访问自己文件夹中的文件
SELECT: auth.uid() = (storage.foldername(name))[1]
UPDATE: auth.uid() = (storage.foldername(name))[1]
DELETE: auth.uid() = (storage.foldername(name))[1]Error Handling
错误处理
Common errors:
| Status | Error | Meaning |
|---|---|---|
| 400 | Invalid bucket name | Bucket name contains invalid characters |
| 404 | Object not found | File doesn't exist |
| 409 | Bucket already exists | Bucket with that name exists |
| 413 | Payload too large | File exceeds size limit |
| 422 | Invalid MIME type | File type not allowed in bucket |
常见错误:
| 状态码 | 错误信息 | 含义 |
|---|---|---|
| 400 | Invalid bucket name | 存储桶名称包含无效字符 |
| 404 | Object not found | 文件不存在 |
| 409 | Bucket already exists | 同名存储桶已存在 |
| 413 | Payload too large | 文件大小超出限制 |
| 422 | Invalid MIME type | 文件类型不被存储桶允许 |
Security Best Practices
安全最佳实践
- Use private buckets for sensitive data
- Implement Storage Policies (RLS) for access control
- Set file size limits to prevent abuse
- Restrict MIME types to expected file types
- Use signed URLs for temporary access to private files
- Organize files in user-specific folders (e.g., )
user-{uuid}/ - Never expose service role key to client applications
- 使用私有存储桶存储敏感数据
- **实现存储策略(RLS)**进行访问控制
- 设置文件大小限制防止滥用
- 限制MIME类型为预期的文件类型
- 使用签名URL为私有文件提供临时访问权限
- 按用户组织文件(例如:)
user-{uuid}/ - 切勿向客户端应用暴露服务角色密钥
File Size Limits
文件大小限制
- Default max file size: 50MB
- Can be configured per bucket up to 5GB (contact Supabase for larger)
- Check bucket settings for current limit
- 默认最大文件大小:50MB
- 可按存储桶配置,最大支持5GB(更大容量需联系Supabase)
- 可查看存储桶设置获取当前限制
API Documentation
API文档
Full Supabase Storage API documentation: https://supabase.com/docs/guides/storage
完整的Supabase Storage API文档:https://supabase.com/docs/guides/storage