development

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

big-blog 2020. 7. 5. 07:37
반응형

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

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

When I change the Origin header, there seems to always be a X-Cache: Miss from cloudfront on the first request then afterwards I get the expected X-Cache: Hit from cloudfront

P.S. It is worth noting that when doing curl -I (capital I) will NOT show the Access-Control-Allow-Origin headers as it only a HEAD, I do -i to make it a GET and scroll up.


My fonts were served correctly until the last push to Heroku... I don't know why, but the wildcard in the CORS allowed origin stopped working. I added all of my prepro and pro domains to the CORS policy in the bucket setting so now it looks like this:

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

UPDATE: add your http://localhost:PORT too


Well, the documentation states that you can stick the configuration as "the cors subresource in your bucket." I took this to mean I would create a file called "cors" at the root of my bucket with the configuration, but this would not work. In the end I had to login to the Amazon S3 administration area and add the configuration within the properties dialog of my bucket.

S3 could use some better documentation...


In my case, I hadn't defined XML namespace and version in CORS configuration. Defining those worked.

Changed

<CORSConfiguration>

to

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

In Amazon S3 CORS configuration (S3 Bucket / Permissions / CORS) if you use this:

<?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 works well for Javascript and CSS files, but It does not work for Font files.

You have to specify the domain to allow CORS using the pattern expressed in the @VKen answer: https://stackoverflow.com/a/25305915/618464

So, use this:

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

Remember to replace "mydomain.com" for your domain.

After this, invalidate the CloudFront cache (CloudFront / Invalidations / Create Invalidation) and It will work.


There is a better and easier way!

I personally prefer using my DNS subdomains to solve this problem. If my CDN is behind cdn.myawesomeapp.com instead of sdf73n7ssa.cloudfront.net then browsers are not going to freakout and block them as cross domain security problems.

To point your subdomain to your AWS Cloudfront domain go to AWS Cloudfront control panel, select your Cloudfront distribution and enter your CDN subdomain into the Alternate Domain Names (CNAMEs) field. Something like cdn.myawesomeapp.com will do.

Now you can go to your DNS provider (like AWS Route 53) and create a CNAME for cdn.myawesomeapp.com pointing to sdf73n7ssa.cloudfront.net.

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


This configuration worked for me. I can list object, retrieve, update and delete.

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
  <CORSRule>
    <AllowedOrigin>http://localhost:3000</AllowedOrigin>
    <AllowedMethod>HEAD</AllowedMethod>
    <AllowedMethod>GET</AllowedMethod>
    <AllowedMethod>PUT</AllowedMethod>
    <AllowedMethod>POST</AllowedMethod>
    <AllowedMethod>DELETE</AllowedMethod>
    <AllowedHeader>*</AllowedHeader>
    <ExposeHeader>ETag</ExposeHeader>
    <ExposeHeader>x-amz-meta-custom-header</ExposeHeader>
  </CORSRule>
</CORSConfiguration>

<ifModule mod_headers.c>

   Header set Access-Control-Allow-Origin: http://domainurl.com

</ifModule>

Simple Solution


Restarting my spring boot application (server) solved the problem for me.

I had configured CORS correctly on S3. The curl was giving the correct response with origin header. Safari was fetching the font correctly. It was only the chrome who was not willing to accept the CORS.

Not sure what exactly caused the behaviour. Must be something to do with If-modified-since


This is not related to fonts but to images, it might be an edge case, but as it happened to me, it might happen to another one. I'll leave this here hoping it will help someone:

If you are in the scenario "I have done everything they told, but it still won't work" probabily it's a cache related problem in Chrome and Safari. Let's suppose your server has a proper CORS configuration set:

<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <CORSRule>
        <AllowedOrigin>*</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <MaxAgeSeconds>3000</MaxAgeSeconds>
    </CORSRule>
</CORSConfiguration>

and in Firefox everything works fine, but in Chrome and Safari it doesn't. If you are accessing to your remote image path from both a simple <img src="http://my.remote.server.com/images/cat.png"> tag and from a js Image element src, like in the following way:

var myImg = new Image()
myImg.crossOrigin = 'Anonymous'
myImg.onload = () => {
  // do stuff (maybe draw the downloaded img on a canvas)
}
myImg.src = 'http://my.remote.server.com/images/cat.png'

You might obtain the No 'Access-Control-Allow-Origin' error in Chrome and Safari. This happen because the first <img> somehow messes up the browser cache, and when you are trying to access the same image later (on the in-code Image element), it simply break. To avoid this, you can add a fictitious GET param to one .src path, in order to force the browser to re-request the image and avoid to use cache, like this:

<img src="http://my.remote.server.com/images/cat.png?nocache=true"></img>

Yes, of course. Firefox supports CORS for fonts, just like the spec requires at http://dev.w3.org/csswg/css3-fonts/#allowing-cross-origin-font-loading


I was experienced the same problem. I didn't have to add a CNAME to my CDD to avoid cross domain problems... I just had to do the following:

버킷 속성-> 권한-> 권한 추가-> 권한 부 여자 : 모든 사람으로 이동하여 '목록'옵션을 확인하십시오.

이것은 그래픽 예입니다. http://i.stack.imgur.com/KOEwy.png

이것이 누군가에게 유용 할 수 있기를 바랍니다.

참고 URL : https://stackoverflow.com/questions/12229844/amazon-s3-cors-cross-origin-resource-sharing-and-firefox-cross-domain-font-loa

반응형