using Microsoft.AspNetCore.StaticFiles; var builder = WebApplication.CreateBuilder(args); // 添加 CORS 策略 builder.Services.AddCors(options => { options.AddPolicy("AllowAll", builder => { builder.AllowAnyOrigin() .AllowAnyMethod() .AllowAnyHeader(); }); }); // 添加 HttpClient 工廠 builder.Services.AddHttpClient(); // 配置命名的 HttpClient builder.Services.AddHttpClient("VideoProcessingClient") .SetHandlerLifetime(TimeSpan.FromMinutes(5)) .ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler()) .ConfigureHttpClient(client => { client.Timeout = TimeSpan.FromMinutes(10); }); // 添加控制器服務 builder.Services.AddControllers(); // 設定最大請求體大小(1 GB) builder.WebHost.ConfigureKestrel(options => { options.Limits.MaxRequestBodySize = 1073741824; // 1 GB options.ListenAnyIP(7860); // Spaces 可能會重定向端口 }); var app = builder.Build(); // 使用 CORS app.UseCors("AllowAll"); // 設定 MIME 類型 var provider = new FileExtensionContentTypeProvider(); provider.Mappings[".wasm"] = "application/wasm"; provider.Mappings[".data"] = "application/data"; // 使用 DefaultFiles 中間件尋找 index.html app.UseDefaultFiles(); // 提供靜態文件,並設置標頭 app.UseStaticFiles(new StaticFileOptions { ContentTypeProvider = provider, OnPrepareResponse = ctx => { Console.WriteLine($"Serving file: {ctx.File.PhysicalPath}"); // 啟用跨源隔離 ctx.Context.Response.Headers["Cross-Origin-Opener-Policy"] = "same-origin"; ctx.Context.Response.Headers["Cross-Origin-Embedder-Policy"] = "require-corp"; // 更新 CSP 配置,確保資源來源正確 ctx.Context.Response.Headers["Content-Security-Policy"] = "default-src 'self'; " + "script-src 'self' 'unsafe-inline' 'unsafe-eval' https://js.stripe.com https://m.stripe.network; " + "style-src 'self' 'unsafe-inline'; " + "worker-src 'self' blob:; " + // 移除外部來源,測試是否因 Stripe 導致失敗 "child-src 'self' blob:; " + // 同上 "frame-src 'self'; " + // 同上 "connect-src 'self' https://api.stripe.com; " + "img-src 'self' data:; " + "font-src 'self';"; } }); // 配置 HTTP 請求管道 app.UseHttpsRedirection(); app.UseAuthorization(); app.MapControllers(); app.Run();