Amazon S3 CORS (Intercambio de recursos de origen cruzado) y carga de fuente entre dominios de Firefox

Ha habido un problema de larga data con Firefox que no carga fonts de origen diferente a la página web actual. Por lo general, el problema surge cuando las fonts se sirven en CDN.

Varias soluciones se han planteado en otras preguntas:

CSS @ font-face no funciona con Firefox, pero funciona con Chrome e IE

Con la presentación de Amazon S3 CORS, ¿hay alguna solución que utilice CORS para abordar el problema de carga de fonts en Firefox?

editar: sería genial ver una muestra de la configuración S3 CORS.

edit2: He encontrado una solución de trabajo sin entender realmente lo que hizo. Si alguien pudiera proporcionar explicaciones más detalladas sobre las configuraciones y la magia de fondo que ocurre en la interpretación de Amazon de la configuración, será muy apreciado, como con nzifnab que puso una recompensa por ello.

    Actualización 10 de septiembre de 2014:

    Ya no deberías necesitar hacer ninguno de los hacks de cadena de consulta a continuación, ya que Cloudfront ahora es compatible con CORS. Consulte http://aws.amazon.com/blogs/aws/enhanced-cloudfront-customization/ y esta respuesta para obtener más información: https://stackoverflow.com/a/25305915/308315


    OK, finalmente conseguí las fonts trabajando usando la configuración a continuación con un pequeño ajuste de ejemplos en la documentación.

    Mis fonts están alojadas en S3, pero al frente de la nube.

    No estoy seguro de por qué funciona, creo que es probable que se el GET y Content-* .

    Si alguien competente con Amazon S3 CORS config puede arrojar algo de luz sobre esto, será muy apreciado.

        https://mydomain.com GET 3000 Content-* Host   https://*.mydomain.com GET 3000 Content-* Host   

    editar:

    Algunos desarrolladores se enfrentan a problemas de almacenamiento en caché de Cloudfront del encabezado Access-Control-Allow-Origin . Este problema ha sido abordado por el personal de AWS en el enlace ( https://forums.aws.amazon.com/thread.jspa?threadID=114646 ) a continuación, comentado por @ Jeff-Atwood.

    A partir del hilo vinculado, se recomienda, como una solución alternativa, utilizar una Cadena de consulta para diferenciar entre llamadas de diferentes dominios. Reproduciré el ejemplo abreviado aquí.

    Usar curl para verificar los encabezados de respuesta:

    Dominio A: a.domain.com

     curl -i -H "Origin: https://a.domain.com" http://hashhashhash.cloudfront.net/font.woff?https_a.domain.com 

    Encabezados de respuesta del dominio A:

     Access-Control-Allow-Origin: https://a.domain.com Access-Control-Allow-Methods: GET Access-Control-Max-Age: 3000 Access-Control-Allow-Credentials: true X-Cache: Miss from Cloudfront 

    Dominio B: b.domain.com

     curl -i -H "Origin: http://b.domain.com" http://hashhashhash.cloudfront.net/font.woff?http_b.domain.com 

    Encabezados de respuesta del dominio B:

     Access-Control-Allow-Origin: http://b.domain.com Access-Control-Allow-Methods: GET Access-Control-Max-Age: 3000 Access-Control-Allow-Credentials: true X-Cache: Miss from Cloudfront 

    Notará que Access-Control-Allow-Origin ha devuelto diferentes valores, que pasaron el caché de Cloudfront.

    Después de algunos ajustes parece que hice que esto funcione sin el hack de cadena de consulta. Más información aquí: http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/RequestAndResponseBehaviorS3Origin.html#RequestS3-cors

    Voy a revisar toda mi configuración para que sea fácil ver lo que he hecho, espero que esto ayude a otros.

    Información de fondo: estoy usando una aplicación de Rails que tiene la gem asset_sync para poner activos en S3. Esto incluye fonts.

    Dentro de la consola S3, hice clic en mi cubo, propiedades y ‘editar configuración de cors’, aquí: Botón de configuración CORS

    Dentro del textarea tengo algo como:

        https://*.example.com GET 3000 *   

    Luego, dentro del panel de Cloudfront ( https://console.aws.amazon.com/cloudfront/home ) creé una distribución, agregué un origen que apuntaba a mi cubo S3 agregando un origen

    Luego se agregó un comportamiento para una ruta predeterminada para apuntar a la configuración de origen I basada en S3. Lo que también hice fue hacer clic en los encabezados de la lista blanca y agregar Origin : agregar un comportamiento y los encabezados de la lista blanca

    Lo que sucede ahora es lo siguiente, que creo que es correcto:

    1) Verifique que los encabezados S3 estén siendo configurados correctamente

     curl -i -H "Origin: https://example.com" https://s3.amazonaws.com/xxxxxxxxx/assets/fonts/my-cool-font.ttf HTTP/1.1 200 OK x-amz-id-2: Ay63Qb5uR98ag47SRJ91+YALtc4onRu1JUJgMTU98Es/pzQ3ckmuWhzzbTgDTCt+ x-amz-request-id: F1FFE275C0FBE500 Date: Thu, 14 Aug 2014 09:39:40 GMT Access-Control-Allow-Origin: https://example.com Access-Control-Allow-Methods: GET Access-Control-Max-Age: 3000 Access-Control-Allow-Credentials: true Vary: Origin, Access-Control-Request-Headers, Access-Control-Request-Method Cache-Control: public, must-revalidate, proxy-revalidate, max-age=180 Last-Modified: Mon, 09 Dec 2013 14:29:04 GMT ETag: "98918ee7f339c7534c34b9f5a448c3e2" Accept-Ranges: bytes Content-Type: application/x-font-ttf Content-Length: 12156 Server: AmazonS3 

    2) Comprobar que Cloudfront funciona con los encabezados

     curl -i -H "Origin: https://example.com" https://xxxxx.cloudfront.net/assets/fonts/my-cool-font.ttf HTTP/1.1 200 OK Content-Type: application/x-font-ttf Content-Length: 12156 Connection: keep-alive Date: Thu, 14 Aug 2014 09:35:26 GMT Access-Control-Allow-Origin: https://example.com Access-Control-Allow-Methods: GET Access-Control-Max-Age: 3000 Access-Control-Allow-Credentials: true Cache-Control: public, must-revalidate, proxy-revalidate, max-age=180 Last-Modified: Mon, 09 Dec 2013 14:29:04 GMT ETag: "98918ee7f339c7534c34b9f5a448c3e2" Accept-Ranges: bytes Server: AmazonS3 Vary: Origin X-Cache: Miss from cloudfront Via: 1.1 77bdacfea247b6cbe84dffa61da5a554.cloudfront.net (CloudFront) X-Amz-Cf-Id: cmCxaUcFf3bT48zpPw0Q-vDDza0nZoWm9-_3qY5pJBhj64iTpkgMlg== 

    (Tenga en cuenta que lo anterior fue una falla de cloudfront porque estos archivos están en caché durante 180 segundos, pero lo mismo estaba funcionando en hits)

    3) Hit cloudfront con un origen diferente (pero uno que está permitido en CORS para el cubo S3) – ¡ Access-Control-Allow-Origin no está en la memoria caché! ¡Hurra!

     curl -i -H "Origin: https://www2.example.com" https://xxxxx.cloudfront.net/assets/fonts/my-cool-font.ttf HTTP/1.1 200 OK Content-Type: application/x-font-ttf Content-Length: 12156 Connection: keep-alive Date: Thu, 14 Aug 2014 10:02:33 GMT Access-Control-Allow-Origin: https://www2.example.com Access-Control-Allow-Methods: GET Access-Control-Max-Age: 3000 Access-Control-Allow-Credentials: true Cache-Control: public, must-revalidate, proxy-revalidate, max-age=180 Last-Modified: Mon, 09 Dec 2013 14:29:04 GMT ETag: "98918ee7f339c7534c34b9f5a448c3e2" Accept-Ranges: bytes Server: AmazonS3 Vary: Origin X-Cache: Miss from cloudfront Via: 1.1 ba7014bad8e9bf2ed075d09443dcc4f1.cloudfront.net (CloudFront) X-Amz-Cf-Id: vy-UccJ094cjdbdT0tcKuil22XYwWdIECdBZ_5hqoTjr0tNH80NQPg== 

    Tenga en cuenta que el dominio ha cambiado correctamente sin una consulta de hack de cadena.

    Cuando cambio el encabezado Origen, parece que siempre hay un X-Cache: Miss from cloudfront en la primera solicitud y luego obtengo el X-Cache: Hit from cloudfront esperado X-Cache: Hit from cloudfront

    PD: Vale la pena señalar que al hacer curl -I (capital I) NO mostrará los encabezados Access-Control-Allow-Origin como solo HEAD, lo hago -i para convertirlo en GET y desplazarme hacia arriba.

    Mis fonts fueron servidas correctamente hasta el último empujón a Heroku … No sé por qué, pero el comodín en el CORS permitió que el origen dejara de funcionar. Agregué todos mis dominios prepro y pro a la política CORS en la configuración del depósito, así que ahora se ve así:

       http://prepro.examle.com https://prepro.examle.com http://examle.com https://examle.com GET 3000 Authorization   

    ACTUALIZACIÓN: agrega tu http://localhost:PORT también

    Bueno, la documentación indica que puede pegar la configuración como “el subrestream cors en su cubo”. Lo interpreté como que crearía un archivo llamado “cors” en la raíz de mi cubo con la configuración, pero esto no funcionaría. Al final tuve que iniciar sesión en el área de administración de Amazon S3 y agregar la configuración dentro del cuadro de diálogo de properties de mi categoría.

    S3 podría usar alguna documentación mejor …

    En mi caso, no había definido el espacio de nombres XML y la versión en la configuración CORS. Definiendo aquellos trabajados.

    Cambiado

      

    a

       

    ¡Hay una manera mejor y más fácil!

    Personalmente prefiero usar mis subdominios DNS para resolver este problema. Si mi CDN está detrás de cdn.myawesomeapp.com en lugar de sdf73n7ssa.cloudfront.net, los navegadores no se van a freakout y los bloquearán como problemas de seguridad entre dominios.

    Para dirigir su subdominio a su dominio de AWS Cloudfront, vaya al panel de control de AWS Cloudfront, seleccione su distribución de Cloudfront e ingrese su subdominio de CDN en el campo de nombres de dominio alternativos (CNAMEs). Algo así como cdn.myawesomeapp.com funcionará.

    Ahora puede ir a su proveedor de DNS (como AWS Route 53) y crear un CNAME para cdn.myawesomeapp.com que apunta a sdf73n7ssa.cloudfront.net.

    http://blog.cloud66.com/cross-origin-resource-sharing-cors-blocked-for-cloudfront-in-rails/

    Esta configuración funcionó para mí. Puedo listar objeto, recuperar, actualizar y eliminar.

        http://localhost:3000 HEAD GET PUT POST DELETE * ETag x-amz-meta-custom-header   
      Header set Access-Control-Allow-Origin: http://domainurl.com  

    Solución simple

    En la configuración CORS de Amazon S3 (S3 Bucket / Permissions / CORS) si usa esto:

        * GET 3000 *  

    CORS funciona bien para archivos Javascript y CSS, pero no funciona para archivos de fonts .

    Debe especificar el dominio para permitir CORS usando el patrón expresado en la respuesta de @VKen: https://stackoverflow.com/a/25305915/618464

    Entonces, usa esto :

        * GET 3000 *   https://*.mydomain.com GET 3000 *   

    Recuerde reemplazar “mydomain.com” para su dominio.

    Después de esto, invalidar el caché de CloudFront (CloudFront / Invalidations / Create Invalidation) y Funcionará.

    Reiniciar mi aplicación de arranque de spring (servidor) resolvió el problema para mí.

    Había configurado CORS correctamente en S3. El rizo daba la respuesta correcta con el encabezado de origen. Safari fue a buscar la fuente correctamente. Solo el cromo no estaba dispuesto a aceptar el CORS.

    No estoy seguro de qué exactamente causó el comportamiento. Debe ser algo relacionado con If-modified-since

    Sí, por supuesto. Firefox es compatible con CORS para fonts, al igual que la especificación en http://dev.w3.org/csswg/css3-fonts/#allowing-cross-origin-font-loading

    Experimenté el mismo problema. No tuve que agregar un CNAME a mi CDD para evitar problemas entre dominios … Solo tenía que hacer lo siguiente:

    Vaya a sus propiedades de Cubo -> Permisos -> Agregar más permisos -> Beneficiario: Todos y marque la opción ‘lista’.

    Este es un ejemplo gráfico. http://i.stack.imgur.com/KOEwy.png

    Espero que esto sea útil para alguien.