Важливе оновлення щодо використання посилань для завантаження згенерованих файлів

Шановні користувачі Tripo!
Ми хочемо повідомити вас про майбутню зміну, яка може вплинути на спосіб доступу до ресурсів нашої платформи та їх використання.
Що змінюється?
Ми впроваджуємо політику CORS для всіх URL-адрес згенерованих артефактів. Це означає, що всі ресурси, розміщені на нашій платформі, потребуватимуть належного опрацювання міждоменних запитів. Іншими словами, ви не зможете безпосередньо надавати згенеровані файли моделей за посиланням, яке повертає вам API Tripo.
Навіщо це впроваджується?
Ця зміна є частиною нашого прагнення підвищити безпеку та запобігти несанкціонованому доступу до ресурсів із різних джерел. CORS (Cross-Origin Resource Sharing) — це механізм, який дає змогу серверам визначати, які зовнішні домени можуть отримувати доступ до ресурсів.
Докладніше про CORS можна дізнатися з посібника MDN.
Вплив на ваш робочий процес
Наразі ми не надаємо заголовки CORS для URL-адрес артефактів. Тому, якщо ви використовуєте ці ресурси безпосередньо у браузері або посилаєтеся на них із зовнішніх доменів, у вас можуть виникнути проблеми.
Щоб забезпечити подальший доступ до цих ресурсів, вам потрібно виконати одну з таких дій:
- Завантажувати та повторно зберігати артефакти локально: ви можете завантажувати артефакти та зберігати їх на своєму backend. Після локального збереження ви зможете надавати ці ресурси зі свого сервера без обмежень CORS.
- Використовувати Edge Proxy (наприклад, Next.js API Route або Cloudflare Workers): ви можете використовувати edge proxy для отримання та надання артефактів, додаючи до відповідей необхідні заголовки CORS. Наприклад:
- Next.js API Route: налаштуйте API route для отримання ресурсів із нашої платформи та їх пересилання з відповідними заголовками CORS.
- Cloudflare Workers: використовуйте Cloudflare Workers для додавання заголовків CORS під час надання наших ресурсів із вашого сервера.
Як підготуватися:
- Перевірте свою інтеграцію: переконайтеся, що ваша система здатна опрацьовувати CORS для URL-адрес артефактів.
- Завантажуйте та зберігайте артефакти: якщо ви не використовуєте edge proxy, розгляньте можливість завантаження та зберігання артефактів на своєму backend.
- Налаштуйте edge proxy: якщо ви використовуєте такі рішення, як Next.js або Cloudflare Workers, оновіть конфігурацію, щоб ресурси надавалися з відповідними заголовками CORS.
- Протестуйте свою систему: перевірте, чи всі міждоменні запити до нашої платформи працюють належним чином.
Потрібні практичні приклади коду? Якщо ви не знаєте, з чого почати, або вважаєте процес складним для реалізації, ми підготували практичні фрагменти коду, які допоможуть вам розпочати роботу. Докладнішу інформацію наведено в Додатку.
FAQ
- Чи втрачено мій згенерований файл?
Ні. Ви можете будь-коли отримати нову URL-адресу через API. - Я не повертаю вашу URL-адресу безпосередньо, але виконую певну постобробку. Чи потрібно мені щось змінювати?
Якщо ви не повертаєте нашу URL-адресу безпосередньо своїм користувачам, ви можете не враховувати цю зміну. Однак ми рекомендуємо стежити за використанням системи, особливо якщо ви помітите різке збільшення кількості помилок або аномальну поведінку.
Потрібна допомога?
Ми розуміємо, що ця зміна може потребувати оновлення вашого робочого процесу. Якщо вам потрібна допомога з налаштуванням edge proxy або у вас виникли запитання щодо цього переходу, зверніться до нашої команди підтримки за адресою [email protected].
Дякуємо за співпрацю, поки ми працюємо над підвищенням безпеки нашої платформи! Бажаємо вам безпечної та продуктивної роботи!
З повагою,
Команда Tripo
Додаток A: підхід із повторним збереженням на backend
Якщо ви використовуєте FastAPI (який легко перенести або адаптувати до будь-якого іншого framework чи мови програмування), ось як можна змінити наявний код для опрацювання CORS і локального збереження артефакту:
Поточний код:
@app.post("/")
def generate(prompt: str) -> str:
resp = ... # API works
return resp.json()['url']
Його можна легко змінити так:
import httpx
import uuid
from fastapi.responses import FileResponse
from fastapi import HTTPException
@app.post("/")
def generate(prompt: str) -> str:
resp = ... # same as above
# Додайте код нижче
file_id = str(uuid.uuid4())
with httpx.Client() as client:
# Завантажте артефакт
response = client.get(url)
# Перевірте, чи був запит успішним
if response.status_code == 200:
# Потім повторно збережіть його
with open(f"./downloaded/{file_id}.glb", "wb") as file:
file.write(response.content)
return file_id
@app.get("/artifact/{file_id}")
def download(file_id: str) -> FileResponse:
if os.path.exists(f"./downloaded/{file_id}.glb"):
return FileResponse(f"./downloaded/{file_id}.glb")
raise HTTPException(status_code=404, detail="Item not found")
Після локального завантаження та збереження файлу ви маєте надавати користувачам нову URL-адресу. Наприклад, якщо ваш застосунок розміщено за адресою https://app.example.com, URL-адреса, яку слід надавати, матиме такий вигляд:
https://app.example.com/artifact/<file_id>
Цей фрагмент коду лише демонструє, як змінити вашу інтеграцію. Однак слід врахувати кілька важливих моментів:
- Додайте належну автентифікацію: переконайтеся, що посилання для завантаження захищені відповідними методами автентифікації, щоб запобігти несанкціонованому доступу.
- Використовуйте надійне сховище: рекомендується зберігати файли в надійніших сховищах, таких як виділені сервери або хмарні рішення для зберігання, наприклад S3 buckets.
- Зберігайте метадані: зберігайте відомості про метадані артефактів у базі даних або іншій системі зберігання для подальшого використання, наприклад відстеження чи аудиту.
Додаток B: підхід із Edge Proxy
Якщо ви розробляєте Single Page Application (SPA) або сервер Backend for Frontend (BFF) і не хочете безпосередньо опрацьовувати завантаження та зберігання файлів на своєму сервері, можна використовувати підхід edge proxy. Він дає змогу отримати файл із нашого сервера, застосувати необхідні заголовки CORS, а потім надати його користувачам.
Рішення 1: завантаження та повторне надсилання файлу за допомогою Edge Functions
Нижче наведено приклад реалізації цього підходу за допомогою Cloudflare Workers. Це рішення усуває проблеми CORS, завантажуючи файл і повторно надсилаючи його з вашого домену.
addEventListener('fetch', event => {
event.respondWith(handleRequest(event.request));
});
async function handleRequest(request) {
// Розберіть URL-адресу запиту
const url = new URL(request.url);
// Отримайте цільову URL-адресу з параметра запиту 'url'
const targetUrl = url.searchParams.get('url');
// Якщо URL-адресу не надано, поверніть помилку
if (!targetUrl) {
return new Response('Please provide a URL parameter', {
status: 400,
headers: {
'Content-Type': 'text/plain',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type'
}
});
}
// Опрацюйте попередній OPTIONS-запит
if (request.method === 'OPTIONS') {
return handleCORS();
}
try {
// Отримайте файл із цільової URL-адреси
const response = await fetch(targetUrl);
// Якщо отримання не вдалося, поверніть помилку
if (!response.ok) {
return new Response(`Failed to fetch from target URL: ${response.statusText}`, {
status: response.status,
headers: corsHeaders()
});
}
// Отримайте тип вмісту з відповіді або використайте octet-stream за замовчуванням
const contentType = response.headers.get('Content-Type') || 'application/octet-stream';
// Отримайте Content-Disposition або створіть його на основі URL-адреси
let contentDisposition = response.headers.get('Content-Disposition');
if (!contentDisposition) {
// Витягніть назву файлу з URL-адреси
const fileName = targetUrl.split('/').pop().split('?')[0] || 'file';
contentDisposition = `attachment; filename="${fileName}"`;
}
// Створіть нову відповідь із заголовками CORS
const newResponse = new Response(response.body, {
status: response.status,
statusText: response.statusText,
headers: {
'Content-Type': contentType,
'Content-Disposition': contentDisposition,
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type',
'Cache-Control': 'public, max-age=3600' // Кешувати протягом 1 години
}
});
return newResponse;
} catch (error) {
return new Response(`Error fetching the file: ${error.message}`, {
status: 500,
headers: corsHeaders()
});
}
}
// Опрацювання попередніх CORS-запитів
function handleCORS() {
return new Response(null, {
status: 204, // Без вмісту
headers: corsHeaders()
});
}
// Створення об'єкта заголовків CORS
function corsHeaders() {
return {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type',
'Access-Control-Max-Age': '86400' // 24 години
};
}
Після налаштування Cloudflare Worker ви можете інтегрувати його у свою SPA, використовуючи наведений нижче JavaScript-код для отримання файлу:
fetch('https://your-worker-url.workers.dev/?url=<target_url>')
.then(response => response.blob())
.then(blob => {
// Створіть посилання для завантаження
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'downloaded-file.pdf';
document.body.appendChild(a);
a.click();
a.remove();
})
.catch(error => console.error('Error:', error));
Це рішення чудово підходить для SPA або BFF-серверів, яким потрібно обійти обмеження CORS під час завантаження та надання файлів кінцевим користувачам. Файл отримується з цільової URL-адреси, проходить через edge proxy і надається з необхідними заголовками CORS.
Рішення 2: налаштування проксі заголовків CORS
Якщо ви віддаєте перевагу простому CORS proxy, скористайтеся цим прикладом від Cloudflare: Cloudflare Workers - CORS Header Proxy
Це дасть змогу простіше опрацьовувати міждоменні запити, водночас дотримуючись політик CORS.
Важливі зауваження:
- Автентифікація: обов'язково належним чином захистіть свої edge functions за допомогою методів автентифікації, таких як API keys, OAuth тощо, щоб запобігти несанкціонованому доступу до файлів.
- Зберігання: хоча цей підхід працює, ми все одно рекомендуємо зберігати артефакт на своєму сервері для подальшого використання, особливо якщо вам потрібно керувати великомасштабними завантаженнями або забезпечити надійний доступ до ресурсів.




