[css] Amazon S3 CORS (Cross-Origin Resource Sharing) 및 Firefox 도메인 간 글꼴로드

Firefox가 현재 웹 페이지와 다른 출처에서 글꼴을로드하지 않는 문제가 오랫동안있었습니다. 일반적으로이 문제는 글꼴이 CDN에서 제공 될 때 발생합니다.

다른 질문에서 다양한 솔루션이 제기되었습니다.

CSS @ font-face는 Firefox에서는 작동하지 않지만 Chrome 및 IE에서는 작동합니다.

Amazon S3 CORS가 도입되면서 CORS를 사용하여 Firefox의 글꼴로드 문제를 해결하는 솔루션이 있습니까?

편집 : S3 CORS 구성의 샘플을 보는 것이 좋습니다.

edit2 : 실제로 무엇을했는지 이해하지 않고 작동하는 솔루션을 찾았습니다. 아마존이 구성을 해석 할 때 발생하는 구성 및 배경 마법에 대해 더 자세한 설명을 제공 할 수 있다면, 현상금을 지불 한 nzifnab와 마찬가지로 크게 감사하겠습니다.



답변

2014 년 9 월 10 일 업데이트 :

Cloudfront는 이제 CORS를 올바르게 지원하므로 더 이상 쿼리 문자열 해킹을 수행 할 필요가 없습니다. 자세한 내용은 http://aws.amazon.com/blogs/aws/enhanced-cloudfront-customization/ 및이 답변을 참조하십시오 : https://stackoverflow.com/a/25305915/308315


좋아, 마침내 문서의 예제에서 약간의 조정으로 아래 구성을 사용하여 글꼴이 작동하도록했습니다.

내 글꼴은 S3에서 호스팅되지만 cloudfront가 앞에 있습니다.

왜 그것이 효과가 있는지 잘 모르겠습니다. 내 추측은 아마도 <AllowedMethod> GETand 일 것입니다 <AllowedHeader> Content-*.

Amazon S3 CORS 구성에 능숙한 사람이 이것에 대해 약간의 지적을 할 수 있다면 크게 감사하겠습니다.

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <CORSRule>
        <AllowedOrigin>https://mydomain.com</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <MaxAgeSeconds>3000</MaxAgeSeconds>
        <AllowedHeader>Content-*</AllowedHeader>
        <AllowedHeader>Host</AllowedHeader>
    </CORSRule>
    <CORSRule>
        <AllowedOrigin>https://*.mydomain.com</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <MaxAgeSeconds>3000</MaxAgeSeconds>
        <AllowedHeader>Content-*</AllowedHeader>
        <AllowedHeader>Host</AllowedHeader>
    </CORSRule>
</CORSConfiguration>

편집하다:

일부 개발자는 Access-Control-Allow-Origin헤더를 캐싱하는 Cloudfront 문제에 직면하고 있습니다 . 이 문제는 @ Jeff-Atwood의 의견이있는 아래 링크 ( https://forums.aws.amazon.com/thread.jspa?threadID=114646 ) 에서 AWS 직원이 해결했습니다 .

연결된 스레드 에서 다른 도메인의 호출을 구분하기 위해 쿼리 문자열 을 사용하는 것이 좋습니다 . 여기서 단축 된 예를 재현하겠습니다.

curl응답 헤더를 확인하는 데 사용 :

도메인 A : a.domain.com

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

도메인 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

도메인 B : b.domain.com

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

도메인 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

당신은 알 수 Access-Control-Allow-OriginCloudFront를 캐싱 과거 가지고 돌아왔다 다른 값을.


답변

약간의 조정 후 쿼리 문자열 해킹없이 작동하는 것으로 보입니다. 자세한 정보는 여기 : http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/RequestAndResponseBehaviorS3Origin.html#RequestS3-cors

나는 내가 한 일을 쉽게 볼 수 있도록 전체 설정을 살펴볼 것입니다.

배경 정보 : Asset_sync gem이있는 Rails 앱을 사용하여 자산을 S3에 넣습니다. 글꼴이 포함됩니다.

S3 콘솔에서 버킷, 속성 및 ‘edit cors configuration’을 클릭했습니다. CORS 구성 버튼

텍스트 영역 안에는 다음과 같은 것이 있습니다.

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <CORSRule>
        <AllowedOrigin>https://*.example.com</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <MaxAgeSeconds>3000</MaxAgeSeconds>
        <AllowedHeader>*</AllowedHeader>
    </CORSRule>
</CORSConfiguration>

그런 다음 Cloudfront 패널 ( https://console.aws.amazon.com/cloudfront/home ) 내에서 배포를 생성하고 S3 버킷을 가리키는 Origin을 추가했습니다.
원점 추가

그런 다음 S3 기반 원점 I 설정을 가리 키도록 기본 경로에 대한 동작을 추가했습니다. 또한 화이트리스트 헤더를 클릭하고 추가했습니다 Origin.
비헤이비어 및 화이트리스트 헤더 추가

지금 일어나는 일은 다음과 같습니다.

1) S3 헤더가 올바르게 설정되어 있는지 확인하십시오

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) Cloudfront가 헤더와 작동하는지 확인

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==

(위의 파일은 180 초 동안 캐시되었지만 히트에서 동일하게 작동했기 때문에 cloudfront에서 누락되었습니다.)

3) 다른 출처로 클라우드 프론트를 치십시오 (그러나 S3 버킷의 CORS에서 허용되는 것)- Access-Control-Allow-Origin캐시되지 않습니다! 예!

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==

쿼리 문자열 해킹없이 도메인이 성공적으로 변경되었습니다.

Origin 헤더를 변경하면 항상 X-Cache: Miss from cloudfront첫 번째 요청 이있는 것으로 보이며 그 후에 예상X-Cache: Hit from cloudfront

추신 : curl -I (자본 I)를 수행 할 때 HEAD만으로 Access-Control-Allow-Origin 헤더를 표시하지 않을 것입니다 .GET으로 만들고 위로 스크롤하기 위해 -i를 수행합니다.


답변

Heroku에 마지막으로 푸시 할 때까지 내 글꼴이 올바르게 제공되었습니다 … 이유를 모르겠지만 CORS의 와일드 카드로 인해 원본이 작동하지 않았습니다. 버킷 설정에서 CORS 정책에 프리프로 및 프로 도메인을 모두 추가 했으므로 이제 다음과 같습니다.

<CORSConfiguration>
    <CORSRule>
        <AllowedOrigin>http://prepro.examle.com</AllowedOrigin>
        <AllowedOrigin>https://prepro.examle.com</AllowedOrigin>
        <AllowedOrigin>http://examle.com</AllowedOrigin>
        <AllowedOrigin>https://examle.com</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <MaxAgeSeconds>3000</MaxAgeSeconds>
        <AllowedHeader>Authorization</AllowedHeader>
    </CORSRule>

</CORSConfiguration>

업데이트 : http://localhost:PORT너무 추가


답변

문서에는 구성을 “버킷의 cors 하위 리소스”로 유지할 수 있다고 명시되어 있습니다. 구성을 사용하여 버킷 루트에 “cors”라는 파일을 만들 겠다는 의미로이 작업을 수행했지만 작동하지 않습니다. 결국 Amazon S3 관리 영역에 로그인하고 properties버킷 대화 상자에 구성을 추가해야했습니다 .

S3는 더 나은 문서를 사용할 수 있습니다 …


답변

이것을 사용하는 경우 Amazon S3 CORS 구성 (S3 버킷 / 권한 / CORS)에서 :

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
    <AllowedOrigin>*</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <MaxAgeSeconds>3000</MaxAgeSeconds>
    <AllowedHeader>*</AllowedHeader>
</CORSRule>

CORS는 Javascript 및 CSS 파일 에서는 잘 작동 하지만 Font files에서는 작동하지 않습니다 .

@VKen 답변에 표시된 패턴을 사용하여 CORS를 허용하도록 도메인을 지정해야합니다. https://stackoverflow.com/a/25305915/618464

따라서 이것을 사용하십시오 :

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
    <AllowedOrigin>*</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <MaxAgeSeconds>3000</MaxAgeSeconds>
    <AllowedHeader>*</AllowedHeader>
</CORSRule>
<CORSRule>
    <AllowedOrigin>https://*.mydomain.com</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <MaxAgeSeconds>3000</MaxAgeSeconds>
    <AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>

도메인의 “mydomain.com”을 교체하십시오.

그런 다음 CloudFront 캐시 (CloudFront / Invalidations / Create Invalidation)를 무효화하면 작동합니다.


답변

필자의 경우 CORS 구성에서 XML 네임 스페이스 및 버전을 정의하지 않았습니다. 그것들을 정의했다.

변경됨

<CORSConfiguration>

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">


답변

더 쉽고 쉬운 방법이 있습니다!

개인적으로이 문제를 해결하기 위해 DNS 하위 도메인을 사용하는 것을 선호합니다. 내 CDN이 sdf73n7ssa.cloudfront.net 대신 cdn.myawesomeapp.com 뒤에 있으면 브라우저는 도메인 간 보안 문제로 기절하지 않으며 차단하지 않습니다.

하위 도메인을 AWS Cloudfront 도메인으로 지정하려면 AWS Cloudfront 제어판으로 이동하여 Cloudfront 배포를 선택하고 CDN 하위 도메인을 CNAME (대체 도메인 이름) 필드에 입력하십시오. cdn.myawesomeapp.com과 같은 것이 할 것입니다.

이제 DNS 제공자 (예 : AWS Route 53)로 이동하여 sdf73n7ssa.cloudfront.net을 가리키는 cdn.myawesomeapp.com에 대한 CNAME을 생성 할 수 있습니다.

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