この度、当社のプラットフォームからのリソースへのアクセスおよび利用方法に影響を与える可能性のある変更についてお知らせいたします。
生成されたすべての成果物URLにCORSポリシーを適用いたします。これは、当社のプラットフォームでホストされているすべてのリソースが、クロスオリジンリクエストに対する適切な処理を必要とすることを意味します。言い換えれば、TripoのAPIが返すリンクを使用して生成されたモデルファイルを直接提供することはできなくなります。
この変更は、セキュリティの向上と、異なるオリジン間のリソースへの不正アクセス防止に対する当社の取り組みの一環です。CORS(Cross-Origin Resource Sharing)は、どの外部ドメインがリソースにアクセスできるかをサーバーが指定するためのメカニズムです。
CORSの詳細については、MDNのガイドを参照してください。
現在、成果物URLにはCORSヘッダーを提供していません。このため、ブラウザや外部ドメインからこれらのリソースを直接使用またはリンクしている場合、問題が発生する可能性があります。
これらのアセットへの継続的なアクセスを確保するためには、以下のいずれかの措置を講じる必要があります。
具体的なコード例が必要ですか? 開始方法がわからない場合や、実装が難しいと感じる場合は、役立つ実用的なコードスニペットを提供しています。詳細については、付録を参照してください。
生成されたファイルは失われますか?
**いいえ。**いつでもAPIから新しいURLを取得できます。
貴社のURLを直接返していませんが、後処理を行っています。心配する必要がありますか?
当社のURLを直接ユーザーに返していない場合は、この変更をスキップできます。ただし、特にシステムでエラーの急増や異常な動作に気づいた場合は、使用状況を監視することをお勧めします。
FastAPI(他のフレームワークや言語への移植や変換が容易です)を使用している場合、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
# Add the code below
file_id = str(uuid.uuid4())
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)
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>
このコードスニペットは、統合を調整する方法を示す単なるデモンストレーションです。ただし、考慮すべき重要な点がいくつかあります。
シングルページアプリケーション (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がセットアップされたら、以下のJavaScriptコードを使用してファイルをフェッチすることで、SPAに統合できます。
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));
このソリューションは、CORS制限をバイパスしながらファイルをエンドユーザーにダウンロードして提供する必要があるSPAやBFFサーバーに最適です。ファイルはターゲットURLからフェッチされ、エッジプロキシを介して渡され、必要なCORSヘッダーとともに提供されます。
シンプルなCORSプロキシをセットアップしたい場合は、Cloudflareが提供するこの例を参照してください:Cloudflare Workers - CORS Header Proxy
これにより、CORSポリシーに準拠しながら、クロスオリジンリクエストをより簡単に処理できるようになります。
moving at the speed of creativity, achieving the depths of imagination.