Мы пишем, чтобы проинформировать вас о предстоящем изменении, которое может повлиять на то, как вы получаете доступ к ресурсам нашей платформы и используете их.
Мы будем принудительно применять политику CORS ко всем URL-адресам сгенерированных артефактов. Это означает, что все ресурсы, размещенные на нашей платформе, потребуют соответствующей обработки для междоменных запросов, или, другими словами, вы не сможете напрямую обслуживать сгенерированные файлы моделей, используя ссылку, которую возвращает API Tripo.
Это изменение является частью нашего стремления улучшить безопасность и предотвратить несанкционированный доступ к ресурсам из разных источников. CORS (Cross-Origin Resource Sharing) — это механизм, который позволяет серверам указывать, какие внешние домены могут получать доступ к ресурсам.
Для получения дополнительной информации о том, что такое CORS, вы можете обратиться к руководству MDN.
В настоящее время мы не предоставляем заголовки CORS для URL-адресов артефактов. В результате, если вы используете или ссылаетесь на эти ресурсы напрямую в браузере или из внешних доменов, у вас могут возникнуть проблемы.
Чтобы обеспечить постоянный доступ к этим активам, вам необходимо предпринять одно из следующих действий:
Нужны практические примеры кода? Если вы не знаете, как начать, или процесс кажется сложным в реализации, мы предоставили практические фрагменты кода, которые помогут вам начать работу. Более подробную информацию см. в Приложении.
Потерян ли мой сгенерированный файл?
Нет. Вы всегда можете получить новый URL-адрес из API в любое время.
Я не возвращаю ваш URL-адрес напрямую, но выполняю некоторую постобработку. Стоит ли мне беспокоиться?
Если вы не возвращаете наш URL-адрес напрямую своим пользователям, вы можете пропустить это изменение. Однако мы рекомендуем отслеживать ваше использование, особенно если вы заметите какие-либо всплески ошибок или аномальное поведение в вашей системе.
Если вы используете FastAPI (который легко портировать или перевести на любой другой фреймворк или язык), вот как вы можете настроить свой существующий код для обработки CORS и сохранения артефакта локально:
Текущий код:
@app.post("/")
def generate(prompt: str) -> str:
resp = ... # API works
return resp.json()['url']
Вы можете легко изменить его на:
import httpx
import uuid
import os
from fastapi.responses import FileResponse
from fastapi import HTTPException
@app.post("/")
def generate(prompt: str) -> str:
resp = ... # same as above
url = resp.json()['url'] # assuming url is extracted from resp
# Add the code below
file_id = str(uuid.uuid4())
# Ensure the directory exists
os.makedirs("./downloaded", exist_ok=True)
with httpx.Client() as client:
# Download the artifact
response = client.get(url)
# Check if the request was successful
if response.status_code == 200:
# Then resave it
with open(f"./downloaded/{file_id}.glb", "wb") as file:
file.write(response.content)
else:
raise HTTPException(status_code=response.status_code, detail="Failed to download artifact")
return file_id
@app.get("/artifact/{file_id}")
def download(file_id: str) -> FileResponse:
file_path = f"./downloaded/{file_id}.glb"
if os.path.exists(file_path):
return FileResponse(file_path)
raise HTTPException(status_code=404, detail="Item not found")
После загрузки и сохранения файла локально вы должны обслуживать своих пользователей с новым URL-адресом. Например, если ваше приложение размещено по адресу https://app.example.com, URL-адрес, который вы должны обслуживать, будет выглядеть следующим образом:
https://app.example.com/artifact/<file_id>
Этот фрагмент кода является лишь демонстрацией того, как настроить вашу интеграцию. Однако есть несколько важных моментов, которые следует учитывать:
Если вы разрабатываете одностраничное приложение (SPA) или бэкенд для фронтенда (BFF) и предпочитаете не обрабатывать загрузку и хранение файлов непосредственно на своем сервере, вы можете использовать подход с граничным прокси. Это позволяет получать файл с нашего сервера, применять необходимые заголовки CORS, а затем передавать его вашим пользователям.
Ниже приведен пример того, как реализовать этот подход с использованием Cloudflare Workers. Это решение позволит решить проблемы CORS путем загрузки файла и его повторной отправки под вашим доменом.
addEventListener('fetch', event => {
event.respondWith(handleRequest(event.request));
});
async function handleRequest(request) {
// Parse the request URL
const url = new URL(request.url);
// Get the target URL from the 'url' query parameter
const targetUrl = url.searchParams.get('url');
// If no URL is provided, return an error
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'
}
});
}
// Handle preflight OPTIONS request
if (request.method === 'OPTIONS') {
return handleCORS();
}
try {
// Fetch the file from the target URL
const response = await fetch(targetUrl);
// If the fetch failed, return the error
if (!response.ok) {
return new Response(`Failed to fetch from target URL: ${response.statusText}`, {
status: response.status,
headers: corsHeaders()
});
}
// Get the content type from the response or default to octet-stream
const contentType = response.headers.get('Content-Type') || 'application/octet-stream';
// Get the content disposition or create one from the URL
let contentDisposition = response.headers.get('Content-Disposition');
if (!contentDisposition) {
// Extract filename from the URL
const fileName = targetUrl.split('/').pop().split('?')[0] || 'file';
contentDisposition = `attachment; filename="${fileName}"`;
}
// Create a new response with CORS headers
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' // Cache for 1 hour
}
});
return newResponse;
} catch (error) {
return new Response(`Error fetching the file: ${error.message}`, {
status: 500,
headers: corsHeaders()
});
}
}
// Handle CORS preflight requests
function handleCORS() {
return new Response(null, {
status: 204, // No content
headers: corsHeaders()
});
}
// Create CORS headers object
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 hours
};
}
После настройки вашего Cloudflare Worker вы можете интегрировать его в свое SPA, используя следующий код JavaScript для получения файла:
fetch('https://your-worker-url.workers.dev/?url=<target_url>')
.then(response => response.blob())
.then(blob => {
// Create a download link
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-адреса, передается через граничный прокси и обслуживается с необходимыми заголовками CORS.
Если вы предпочитаете настроить простой прокси-сервер CORS, вы можете обратиться к этому примеру, предоставленному Cloudflare: Cloudflare Workers - CORS Header Proxy
Это позволит вам легче обрабатывать междоменные запросы, по-прежнему соблюдая политики CORS.
moving at the speed of creativity, achieving the depths of imagination.