javascript - headers - Política de CORS sobre la imagen en caché
cors javascript (4)
¿Qué configuración de CORS está aplicando? Esta publicación sugiere que los comodines en AllowedOrigin
se AllowedOrigin
(en lugar de enviarse literalmente, parece ser un comportamiento no documentado); y el valor del encabezado Access-Control-Allow-Origin
se guarda en caché para solicitudes posteriores, lo que causa problemas similares a lo que informa.
En cromo 22 y safari 6.
Carga de imágenes de s3 para su uso en un lienzo (con extracción como una intención principal) usando un bucket S3 habilitado para CORS, con el siguiente código:
<!-- In the html -->
<img src="http://s3....../bob.jpg" />
// In the javascript, executed after the dom is rendered
this.img = new Image();
this.img.crossOrigin = ''anonymous'';
this.img.src = "http://s3....../bob.jpg";
He observado lo siguiente:
- Inhabilitar cachés
- Todo funciona bien, ambas imágenes cargan
Luego intentándolo con cachés habilitados:
- Habilitar cachés
- Carga de imágenes DOM, la imagen de lienzo crea una excepción de seguridad dom
Si modifico la parte javascript del código para anexar una cadena de consulta, haga lo siguiente:
this.img = new Image();
this.img.crossOrigin = ''anonymous'';
this.img.src = "http://s3....../bob.jpg?_";
Todo funciona, incluso con el almacenamiento en caché habilitado por completo. Llegué al caché como un problema al usar un proxy http y observar que en el caso de falla, la imagen no se está solicitando realmente desde el servidor.
La conclusión que me veo obligado a extraer es que la caché de imágenes está guardando los encabezados de solicitud originales, que luego se utilizan para la siguiente solicitud CORS habilitada, y la excepción de seguridad se genera debido a la violación de la misma política de origen.
¿Es este comportamiento intencionado?
Editar: Funciona en Firefox.
Edit2: política de Cors en el cubo s3
<?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>
Estoy usando de par en par porque estoy probando desde mi caja local en este momento. Esto aún no está en producción.
Edit3: política actualizada de cors para especificar un origen
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>http://localhost:5000</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
</CORSRule>
</CORSConfiguration>
Cabeceras salientes verificadas:
Origin http://localhost:5000
Accept */*
Referer http://localhost:5000/builder
Accept-Encoding gzip,deflate,sdch
Accept-Language en-US,en;q=0.8
Accept-Charset ISO-8859-1,utf-8;q=0.7,*;q=0.3
Encabezados entrantes:
Access-Control-Allow-Origin http://localhost:5000
Access-Control-Allow-Methods GET
Access-Control-Allow-Credentials true
Todavía falla en Chrome si no reventar el caché al cargar en el lienzo.
Editar 4:
Solo noté esto en el caso de falla.
Encabezados salientes:
GET /373c88b12c7ba7c513081c333d914e8cbd2cf318b713d5fb993ec1e7 HTTP/1.1
Host amir.s3.amazonaws.com
User-Agent Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.91 Safari/537.4
Accept */*
Referer http://localhost:5000/builder
Accept-Encoding gzip,deflate,sdch
Accept-Language en-US,en;q=0.8
Accept-Charset ISO-8859-1,utf-8;q=0.7,*;q=0.3
If-None-Match "99c958e2196c60aa8db385b4be562a92"
If-Modified-Since Sat, 29 Sep 2012 13:53:34 GMT
Encabezados entrantes:
HTTP/1.1 304 Not Modified
x-amz-id-2 3bzllzox/vZPGSn45Y21/vh1Gm/GiCEoIWdDxbhlfXAD7kWIhMKqiSEVG/Q5HqQi
x-amz-request-id 48DBC4559B5B840D
Date Sat, 29 Sep 2012 13:55:21 GMT
Last-Modified Sat, 29 Sep 2012 13:53:34 GMT
ETag "99c958e2196c60aa8db385b4be562a92"
Server AmazonS3
Creo que esta es la primera solicitud, desencadenada por el dom. No obstante, no sé si no es la solicitud de JavaScript.
El comportamiento descrito parece lógico ya que la clave de entrada de caché es un URI de destino (consulte 7234 Protocolo de transferencia de hipertexto (HTTP / 1.1): almacenamiento en caché ). Para solucionar el problema y usar efectivamente el caché, es necesario que el servidor de alojamiento de imágenes dé la misma respuesta en ambos casos.
Una opción es hacer que el agente de usuario envíe el encabezado HTTP de Origin
en la primera solicitud también (dado que la respuesta con la clave targetUri
ya no está en un caché):
<img src="targetUri" crossorigin="anonymous" />
Otra opción es configurar el servidor de alojamiento de imágenes para enviar encabezados HTTP relacionados con CORS, independientemente de si la solicitud contiene encabezado HTTP de Origin
. Para obtener más información, consulte S3 CORS, siempre envíe Vary: Discusión de origen en .
También puede informar al agente de usuario que las respuestas son sensibles al encabezado HTTP de solicitud de Origin
utilizando el encabezado Vary
Response. La desventaja es que probablemente el agente de usuario usará el encabezado Vary
solo como un validador de respuesta (y no como parte de una clave de entrada de caché) y almacenará solo una instancia de respuesta única para un URI objetivo que hace más difícil el uso efectivo del caché. Para obtener más información, consulte El estado del almacenamiento en caché del navegador, artículo revisado por Mark Nottingham.
El problema es que la imagen se almacena en caché a partir de una solicitud anterior, sin los encabezados CORS necesarios. Por lo tanto, cuando lo solicita de nuevo, para el lienzo, con el ''crossorigin'' especificado, el navegador usa la versión en caché, no ve los encabezados necesarios, y provoca un error CORS. Cuando agrega el ''? _'' A la url, el navegador ignora la caché, ya que esta es otra URL. Eche un vistazo a este hilo: https://bugs.chromium.org/p/chromium/issues/detail?id=409090
Firefox y otros navegadores no tienen ese problema.
Tuve un problema muy similar y lo resolví agregando el siguiente encabezado a la respuesta del servidor.
''Vary'': ''Origin''
Después de agregar el encabezado, todas mis solicitudes se almacenaron en caché.