mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-02-02 22:37:32 +00:00
[bugfix] fix service worker opaqueredirect error and ensure SW controls page before mount
Fixes two related issues with the auth service worker: 1. Opaqueredirect network error: - Service workers cannot return opaqueredirect responses to the page - When using redirect: 'manual', cross-origin redirects produce opaqueredirect - Solution: Re-fetch with redirect: 'follow' when opaqueredirect detected - Browser automatically strips auth headers on cross-origin redirects to GCS 2. Race condition on first load: - App was mounting before service worker registration completed - Images could load before SW gained control of the page - Solution: Await SW registration before mounting app - Changed void import() to await import() at all levels This fixes the pattern where hard refresh works (bypasses SW) but normal refresh fails (SW intercepts but returns invalid opaqueredirect response).
This commit is contained in:
@@ -67,15 +67,28 @@ self.addEventListener('fetch', (event) => {
|
||||
})
|
||||
)
|
||||
|
||||
// If redirected to external storage (GCS), follow without auth headers
|
||||
// The signed URL contains its own authentication in query params
|
||||
if (
|
||||
response.type === 'opaqueredirect' ||
|
||||
response.status === 302 ||
|
||||
response.status === 301
|
||||
) {
|
||||
// Handle redirects to external storage (e.g., GCS signed URLs)
|
||||
if (response.type === 'opaqueredirect') {
|
||||
// Opaqueredirect: redirect occurred but response is opaque (headers not accessible)
|
||||
// Re-fetch the original /api/view URL with redirect: 'follow'
|
||||
// Browser will:
|
||||
// 1. Send auth headers to /api/view (same-origin)
|
||||
// 2. Receive 302 redirect to GCS
|
||||
// 3. Automatically strip auth headers when following cross-origin redirect
|
||||
// 4. Use GCS signed URL authentication instead
|
||||
return fetch(event.request.url, {
|
||||
method: 'GET',
|
||||
headers: headers,
|
||||
redirect: 'follow'
|
||||
})
|
||||
}
|
||||
|
||||
// Non-opaque redirect (status visible) - shouldn't normally happen with redirect: 'manual'
|
||||
// but handle as fallback
|
||||
if (response.status === 302 || response.status === 301) {
|
||||
const location = response.headers.get('location')
|
||||
if (location) {
|
||||
// Follow redirect manually - do NOT include auth headers for external URLs
|
||||
return fetch(location, {
|
||||
method: 'GET',
|
||||
redirect: 'follow'
|
||||
|
||||
@@ -86,8 +86,9 @@ app
|
||||
})
|
||||
|
||||
// Register auth service worker after Pinia is initialized (cloud-only)
|
||||
// Wait for registration to complete before mounting to ensure SW controls the page
|
||||
if (isCloud) {
|
||||
void import('@/platform/auth/serviceWorker')
|
||||
await import('@/platform/auth/serviceWorker')
|
||||
}
|
||||
|
||||
app.mount('#vue-app')
|
||||
|
||||
@@ -5,5 +5,5 @@ import { isCloud } from '@/platform/distribution/types'
|
||||
* Tree-shaken for desktop/localhost builds via compile-time constant.
|
||||
*/
|
||||
if (isCloud) {
|
||||
void import('./register')
|
||||
await import('./register')
|
||||
}
|
||||
|
||||
@@ -54,4 +54,4 @@ function setupCacheInvalidation(): void {
|
||||
})
|
||||
}
|
||||
|
||||
void registerAuthServiceWorker()
|
||||
await registerAuthServiceWorker()
|
||||
|
||||
Reference in New Issue
Block a user