Angular Service Worker ngsw-config.json S3 / Cloudflare-Image-Caching CORS-Fehler
Wenn ich in einer Angular 9-App dieses Bild-Caching-Snippet zu ngsw-config.json hinzufüge, wird ein CORS-Fehler angezeigt und Bilder werden nicht angezeigt. Wenn ich dieses Snippet entferne, funktioniert die App korrekt (ohne Fehler).
Der Zugriff auf den Abruf unter 'https://assets.myurl.net/images/banner.jpg' vom Ursprung 'https: // localhost: 8100' wurde durch die CORS-Richtlinie blockiert: Kein Header 'Access-Control-Allow-Origin' ist in der angeforderten Ressource vorhanden. Wenn eine undurchsichtige Antwort Ihren Anforderungen entspricht, setzen Sie den Anforderungsmodus auf "no-cors", um die Ressource mit deaktiviertem CORS abzurufen.
ngsw-config.json (Snippet):
"assetGroups": [{
"name": "cdn",
"installMode": "lazy",
"updateMode": "lazy",
"resources": {
"urls": [
"https://assets.myurl.net/**"
]
}
}]
Bilder werden in einem AWS S3-Bucket mit CORS-Konfiguration gespeichert:
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
</CORSRule>
</CORSConfiguration>
- Cloudflare wird als CDN (und DNS) verwendet.
- Die App ist auf den neuesten 9.x-Versionen verfügbar: @angular 9.2.1, @ angle / service-worker 9.1.12.
- Das Hinzufügen von crossorigin = "anonym" zu img- und Bild-Tags schien nicht zu helfen.
Schritte zum konsistenten Reproduzieren des Fehlers in Chrome / PC:
- Browser-Cache löschen
- Öffnen Sie den Browser privat / inkognito
- Zur Website gehen - Bilder zeigen okay
- Klicken Sie auf Aktualisieren - Bilder werden nicht mehr angezeigt - CORS-Fehler in der Browserkonsole
AKTUALISIEREN
Basierend auf diesem Beitrag ( S3 gibt keine Access-Control-Allow-Origin-Header zurück? ) Scheint das Problem zu sein, dass der Service Worker keinen Origin im Anforderungsheader sendet (S3 sendet also keine Access-Control-Header).
Service Worker-Anfrage (von der Chrome-Konsole kopiert):
Request URL: https://assets.myurl.net/images/banner.jpg
Referrer Policy: strict-origin-when-cross-origin
Provisional headers are shown
Referer: https://localhost:8100/
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36
Stellen Sie zunächst bei jeder Anforderung einen Origin-Header sicher. Wenn kein Origin-Header gesendet wird, sendet S3 keine Header für die Zugriffssteuerung, da S3 sie für irrelevant hält (und dies normalerweise der Fall ist). Ein Browser (für den der CORS-Mechanismus vorgesehen ist) sendet automatisch einen Origin-Header, wenn er originäre HTTP-Anforderungen über XMLHTTPRequest ausführt.
Basierend auf diesem Beitrag ( S3 - Access-Control-Allow-Origin-Header ) wurde das S3-Cors-Skript aktualisiert und enthält nun Folgendes:
<AllowedMethod>HEAD</AllowedMethod>
<AllowedHeader>*</AllowedHeader>
Durch Hinzufügen von crossorigin = "anonym" zu img-Tags wird der Anforderungsheader des Service Workers nicht geändert. Das Problem wird also nicht behoben.
Der Cloudflare-Cache wurde gelöscht.
Dieser obskure Beitrag (https://community.cloudflare.com/t/access-control-allow-origin-headers-stripped/158102/2) beinhaltet:
Wenn Sie die CORS-Konfiguration auf Ihrem Ursprungswebserver hinzufügen oder ändern, werden die CORS-Header NICHT aktualisiert, wenn der Cloudflare-Cache nach URL gelöscht wird.
Ich habe das Bild banner.jpg zwischengespeichert, indem ich einen zufälligen Querystring hinzugefügt habe (dh banner.jpg? Q = abc). Das Bannerbild wird immer korrekt angezeigt (während die anderen Bilder weiterhin Cors-Fehler zeigen). Der Service Worker-Cache auf der Registerkarte "Anwendung"> "Cache-Speicher" der Chrome-Konsole zeigt an, dass das Image zwischengespeichert ist. Cloudflare-Caching-Konfiguration "Caching Level" = Standard "liefert jedes Mal eine andere Ressource, wenn sich die Abfragezeichenfolge ändert".
Wenn ich jedoch ein neues Bild in S3 banner01.jpg hochlade (dh nicht bereits von Cloudflare zwischengespeichert), wird ein cors-Fehler angezeigt, der dieses Bild anzeigt. Ich habe dies drei weitere Male versucht, indem ich verschiedene Bildnamen hochgeladen habe und keinen cors-Fehler erhalten habe. Interessanterweise zeigen sogar die neuen Bilder eine Stunde später Cors-Fehler.
Ein Curl-Befehl (der Origin nicht in der Kopfzeile angibt) wird auf meinem lokalen PC erfolgreich ausgeführt. Die Antwort enthält keine CORS-Header. z.B
curl -v "https://assets.myurl.net/images/banner.jpg"
Durch Hinzufügen des Ursprungs zum Befehl curl werden CORS-Header zurückgegeben. z.B
curl -v --header "Origin: https://www.example.com" "https://assets.myurl.net/images/banner.jpg"
access-control-allow-origin: https://www.example.com
access-control-allow-methods: GET, HEAD
access-control-allow-credentials: true
UPDATE 2
Ich kann nicht erklären, warum, aber Chrome gibt jetzt cors-Header in der Angular Service Worker-Abrufantwort zurück. Die Anforderung enthält KEINEN Origin-Header.
accept-ranges: bytes
access-control-allow-methods: GET, HEAD
access-control-allow-origin: *
Safari jedoch nicht. Alle Browser scheinen in Ordnung zu sein, aber Safari zeigt immer noch Cors-Fehler an.
Antworten
Gehen Sie zu Ihrem S3-Eimer. Klicken Sie auf Berechtigungen und dann auf CORS-Konfiguration. Wenn Sie eine CORS-Konfiguration haben, ändern Sie den zulässigen Ursprung folgendermaßen:
<AllowedOrigin>*</AllowedOrigin>
ZU
<AllowedOrigin>http://*</AllowedOrigin>
<AllowedOrigin>https://*</AllowedOrigin>
Wenn Sie keine CORS-Konfiguration haben, fügen Sie eine Konfiguration wie die folgende hinzu:
<CORSConfiguration>
<CORSRule>
<AllowedOrigin>http://*</AllowedOrigin>
<AllowedOrigin>https://*</AllowedOrigin>
<AllowedMethod>PUT</AllowedMethod>
<AllowedMethod>POST</AllowedMethod>
<AllowedMethod>DELETE</AllowedMethod>
<AllowedMethod>GET</AllowedMethod>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
</CORSRule>
</CORSConfiguration>