Resolving CORS Errors Caused by S3 and WebKit's Disk Cache

Overview of the Issue When displaying images within the chat window of a chatbot service on Chrome and Safari for iOS (SP), the images appear correctly upon first viewing. However, reopening the window results in CORS errors and the images fail to display. This issue does not occur on Chrome for macOS (PC). Cause of the Issue The client-side was hitting a backend API which generated signed URLs from S3 to fetch images. Although CORS settings for S3 were appropriately configured to allow the frontend URL, a CORS error occurred during the second access on iOS devices due to the browser's disk cache being used, and the Access-Control-Allow-Origin header not being included in the response. Solution Browsers using WebKit as their rendering engine (Chrome for iOS, Safari for iOS, Safari for macOS) have been observed to omit CORS-related headers (Access-Control-Allow-Origin) when caching static resources like images. To resolve this issue, we explicitly included the ResponseCacheControl: 'no-cache' option in the GetObject request when fetching images from S3. This ensured that all image requests were made over the network, preventing CORS errors caused by cached responses. const command = new GetObjectCommand({ Bucket: bucketName, Key: key, ResponseCacheControl: 'no-cache' // Disable cache }) Conclusion By understanding the behavior of WebKit's disk cache and its impact on CORS settings, we were able to implement a robust solution that ensures consistent behavior across multiple platforms. This approach not only resolved the immediate issue of CORS errors in iOS but also highlighted the importance of considering browser-specific caching behavior when designing web applications that interact with secure resources like S3. Through strategic use of response headers, we can effectively manage how resources are cached and ensure compliance with CORS policies, thereby enhancing the user experience across different devices and browsers.

Jan 18, 2025 - 07:47
Resolving CORS Errors Caused by S3 and WebKit's Disk Cache

Overview of the Issue

When displaying images within the chat window of a chatbot service on Chrome and Safari for iOS (SP), the images appear correctly upon first viewing. However, reopening the window results in CORS errors and the images fail to display. This issue does not occur on Chrome for macOS (PC).

Cause of the Issue

The client-side was hitting a backend API which generated signed URLs from S3 to fetch images. Although CORS settings for S3 were appropriately configured to allow the frontend URL, a CORS error occurred during the second access on iOS devices due to the browser's disk cache being used, and the Access-Control-Allow-Origin header not being included in the response.

Solution

Browsers using WebKit as their rendering engine (Chrome for iOS, Safari for iOS, Safari for macOS) have been observed to omit CORS-related headers (Access-Control-Allow-Origin) when caching static resources like images.

To resolve this issue, we explicitly included the ResponseCacheControl: 'no-cache' option in the GetObject request when fetching images from S3. This ensured that all image requests were made over the network, preventing CORS errors caused by cached responses.

const command = new GetObjectCommand({
  Bucket: bucketName,
  Key: key,
  ResponseCacheControl: 'no-cache'  // Disable cache
})

Conclusion

By understanding the behavior of WebKit's disk cache and its impact on CORS settings, we were able to implement a robust solution that ensures consistent behavior across multiple platforms. This approach not only resolved the immediate issue of CORS errors in iOS but also highlighted the importance of considering browser-specific caching behavior when designing web applications that interact with secure resources like S3. Through strategic use of response headers, we can effectively manage how resources are cached and ensure compliance with CORS policies, thereby enhancing the user experience across different devices and browsers.