- Update BUILDING.md with current build system information - Modernize various README files across the project - Update CHANGELOG.md with recent changes - Improve documentation consistency and formatting - Update platform-specific documentation (iOS, Electron, Docker) - Enhance test documentation and build guides
267 lines
7.6 KiB
Markdown
267 lines
7.6 KiB
Markdown
# CORS Image Loading Solution
|
|
|
|
## Overview
|
|
|
|
This document describes the implementation of a comprehensive image loading solution that works in a cross-origin isolated environment (required for SharedArrayBuffer support) while accepting images from any domain.
|
|
|
|
## Problem Statement
|
|
|
|
When using SharedArrayBuffer (required for absurd-sql), browsers enforce a cross-origin isolated environment with these headers:
|
|
|
|
- `Cross-Origin-Opener-Policy: same-origin`
|
|
- `Cross-Origin-Embedder-Policy: require-corp`
|
|
|
|
This isolation prevents loading external resources (including images) unless they have proper CORS headers, which most image hosting services don't provide.
|
|
|
|
## Solution Architecture
|
|
|
|
### 1. Multi-Tier Proxy System
|
|
|
|
The solution uses a multi-tier approach to handle images from various sources:
|
|
|
|
#### Tier 1: Specific Domain Proxies (Development Only)
|
|
|
|
- **TimeSafari Images**: `/image-proxy/` → `https://image.timesafari.app/`
|
|
- **Flickr Images**: `/flickr-proxy/` → `https://live.staticflickr.com/`
|
|
- **Imgur Images**: `/imgur-proxy/` → `https://i.imgur.com/`
|
|
- **GitHub Raw**: `/github-proxy/` → `https://raw.githubusercontent.com/`
|
|
- **Unsplash**: `/unsplash-proxy/` → `https://images.unsplash.com/`
|
|
|
|
#### Tier 2: Universal CORS Proxy (Development Only)
|
|
|
|
- **Any External Domain**: Uses `https://api.allorigins.win/raw?url=` for arbitrary domains
|
|
|
|
#### Tier 3: Direct Loading (Production)
|
|
|
|
- **Production Mode**: All images load directly without proxying
|
|
|
|
### 2. Smart URL Transformation
|
|
|
|
The `transformImageUrlForCors` function automatically:
|
|
|
|
- Detects the image source domain
|
|
- Routes through appropriate proxy in development
|
|
- Preserves original URLs in production
|
|
- Handles edge cases (data URLs, relative paths, etc.)
|
|
|
|
## Implementation Details
|
|
|
|
### Configuration Files
|
|
|
|
#### `vite.config.common.mts`
|
|
|
|
```typescript
|
|
server: {
|
|
headers: {
|
|
// Required for SharedArrayBuffer support
|
|
'Cross-Origin-Opener-Policy': 'same-origin',
|
|
'Cross-Origin-Embedder-Policy': 'require-corp'
|
|
},
|
|
proxy: {
|
|
// Specific domain proxies with CORS headers
|
|
'/image-proxy': { /* TimeSafari images */ },
|
|
'/flickr-proxy': { /* Flickr images */ },
|
|
'/imgur-proxy': { /* Imgur images */ },
|
|
'/github-proxy': { /* GitHub raw images */ },
|
|
'/unsplash-proxy': { /* Unsplash images */ }
|
|
}
|
|
}
|
|
```
|
|
|
|
#### `src/libs/util.ts`
|
|
|
|
```typescript
|
|
export function transformImageUrlForCors(imageUrl: string): string {
|
|
// Development mode: Transform URLs to use proxies
|
|
// Production mode: Return original URLs
|
|
|
|
// Handle specific domains with dedicated proxies
|
|
// Fall back to universal CORS proxy for arbitrary domains
|
|
}
|
|
```
|
|
|
|
### Usage in Components
|
|
|
|
All image loading in components uses the transformation function:
|
|
|
|
```typescript
|
|
// In Vue components
|
|
import { transformImageUrlForCors } from "../libs/util";
|
|
|
|
// Transform image URL before using
|
|
const imageUrl = transformImageUrlForCors(originalImageUrl);
|
|
```
|
|
|
|
```html
|
|
<!-- In templates -->
|
|
<img :src="transformImageUrlForCors(imageUrl)" alt="Description" />
|
|
```
|
|
|
|
## Benefits
|
|
|
|
### ✅ SharedArrayBuffer Support
|
|
|
|
- Maintains cross-origin isolation required for SharedArrayBuffer
|
|
- Enables fast SQLite database operations via absurd-sql
|
|
- Provides better performance than IndexedDB fallback
|
|
|
|
### ✅ Universal Image Support
|
|
|
|
- Handles images from any domain
|
|
- No need to pre-configure every possible image source
|
|
- Graceful fallback for unknown domains
|
|
|
|
### ✅ Development/Production Flexibility
|
|
|
|
- Proxy system only active in development
|
|
- Production uses direct URLs for maximum performance
|
|
- No proxy server required in production
|
|
|
|
### ✅ Automatic Detection
|
|
|
|
- Smart URL transformation based on domain patterns
|
|
- Preserves relative URLs and data URLs
|
|
- Handles edge cases gracefully
|
|
|
|
## Testing
|
|
|
|
### Automated Testing
|
|
|
|
Run the test suite to verify URL transformation:
|
|
|
|
```typescript
|
|
import { testCorsImageTransformation } from './libs/test-cors-images';
|
|
|
|
// Console output shows transformation results
|
|
testCorsImageTransformation();
|
|
```
|
|
|
|
### Visual Testing
|
|
|
|
Create test image elements to verify loading:
|
|
|
|
```typescript
|
|
import { createTestImageElements } from './libs/test-cors-images';
|
|
|
|
// Creates visual test panel in browser
|
|
createTestImageElements();
|
|
```
|
|
|
|
### Manual Testing
|
|
|
|
1. Start development server: `npm run dev`
|
|
2. Open browser console to see transformation logs
|
|
3. Check Network tab for proxy requests
|
|
4. Verify images load correctly from various domains
|
|
|
|
## Security Considerations
|
|
|
|
### Development Environment
|
|
|
|
- CORS proxies are only used in development
|
|
- External proxy services (allorigins.win) are used for testing
|
|
- No sensitive data is exposed through proxies
|
|
|
|
### Production Environment
|
|
|
|
- All images load directly without proxying
|
|
- No dependency on external proxy services
|
|
- Original security model maintained
|
|
|
|
### Privacy
|
|
|
|
- Image URLs are not logged or stored by proxy services
|
|
- Proxy requests are only made during development
|
|
- No tracking or analytics in proxy chain
|
|
|
|
## Performance Impact
|
|
|
|
### Development
|
|
|
|
- Slight latency from proxy requests
|
|
- Additional network hops for external domains
|
|
- More verbose logging for debugging
|
|
|
|
### Production
|
|
|
|
- No performance impact
|
|
- Direct image loading as before
|
|
- No proxy overhead
|
|
|
|
## Troubleshooting
|
|
|
|
### Common Issues
|
|
|
|
#### Images Not Loading in Development
|
|
|
|
1. Check console for proxy errors
|
|
2. Verify CORS headers are set
|
|
3. Test with different image URLs
|
|
4. Check network connectivity to proxy services
|
|
|
|
#### SharedArrayBuffer Not Available
|
|
|
|
1. Verify CORS headers are set in server configuration
|
|
2. Check that site is served over HTTPS (or localhost)
|
|
3. Ensure browser supports SharedArrayBuffer
|
|
|
|
#### Proxy Service Unavailable
|
|
|
|
1. Check if allorigins.win is accessible
|
|
2. Consider using alternative CORS proxy services
|
|
3. Temporarily disable CORS headers for testing
|
|
|
|
### Debug Commands
|
|
|
|
```bash
|
|
# Check if SharedArrayBuffer is available
|
|
console.log(typeof SharedArrayBuffer !== 'undefined');
|
|
|
|
# Test URL transformation
|
|
import { transformImageUrlForCors } from './libs/util';
|
|
console.log(transformImageUrlForCors('https://example.com/image.jpg'));
|
|
|
|
# Run comprehensive tests
|
|
import { testCorsImageTransformation } from './libs/test-cors-images';
|
|
testCorsImageTransformation();
|
|
```
|
|
|
|
## Migration Guide
|
|
|
|
### From Previous Implementation
|
|
|
|
1. CORS headers are now required for SharedArrayBuffer
|
|
2. Image URLs automatically transformed in development
|
|
3. No changes needed to existing image loading code
|
|
4. Test thoroughly in both development and production
|
|
|
|
### Adding New Image Sources
|
|
|
|
1. Add specific proxy for frequently used domains
|
|
2. Update `transformImageUrlForCors` function
|
|
3. Add CORS headers to proxy configuration
|
|
4. Test with sample images
|
|
|
|
## Future Enhancements
|
|
|
|
### Possible Improvements
|
|
|
|
1. **Local Proxy Server**: Run dedicated proxy server for development
|
|
2. **Caching**: Cache proxy responses for better performance
|
|
3. **Fallback Chain**: Multiple proxy services for reliability
|
|
4. **Image Optimization**: Compress/resize images through proxy
|
|
5. **Analytics**: Track image loading success/failure rates
|
|
|
|
### Alternative Approaches
|
|
|
|
1. **Service Worker**: Intercept image requests at service worker level
|
|
2. **Build-time Processing**: Pre-process images during build
|
|
3. **CDN Integration**: Use CDN with proper CORS headers
|
|
4. **Local Storage**: Cache images in browser storage
|
|
|
|
## Conclusion
|
|
|
|
This solution provides a robust, scalable approach to image loading in a cross-origin isolated environment while maintaining the benefits of SharedArrayBuffer support. The multi-tier proxy system ensures compatibility with any image source while optimizing for performance and security.
|
|
|
|
For questions or issues, refer to the troubleshooting section or consult the development team.
|