Google 由于内容安全策略,字体未加载
Google font not loading because of content security policy
我有一个渐进式网络应用程序。我正在使用 Google 字体,并且在我的 service worker 中使用 workbox。
我的内容安全策略定义为:
// Omitting all the other directives
style-src 'self' https://fonts.googleapis.com 'unsafe-inline';
font-src 'self' https://fonts.gstatic.com;
connect-src 'self';
我已经按照配方 here 设置了工作箱来缓存字体。代码如下:
workbox.routing.registerRoute(
/^https:\/\/fonts\.googleapis\.com/,
new workbox.strategies.StaleWhileRevalidate({
cacheName: 'google-fonts-stylesheets',
})
);
workbox.routing.registerRoute(
/^https:\/\/fonts\.gstatic\.com/,
new workbox.strategies.CacheFirst({
cacheName: 'google-fonts-webfonts',
plugins: [
new workbox.cacheableResponse.Plugin({
statuses: [0, 200],
}),
new workbox.expiration.Plugin({
maxAgeSeconds: 60 * 60 * 24 * 365,
maxEntries: 30,
}),
],
})
);
这里的问题是,当我尝试在浏览器 (Google Chrome / Safari) 或独立应用程序中加载我的应用程序时,字体不会加载。纠结了好久,Chrome 终于在控制台报错了:
Refused to connect to 'https://fonts.googleapis.com/css?family=Montserrat|Quicksand&display=swap' because it violates the following Content Security Policy directive: "connect-src 'self'".
Uncaught (in promise) no-response: no-response :: [{"url":"https://fonts.googleapis.com/css?family=Montserrat|Quicksand&display=swap","error":{}}]
at o.makeRequest (https://storage.googleapis.com/workbox-cdn/releases/4.2.0/workbox-strategies.prod.js:1:3983)
GET https://fonts.googleapis.com/css?family=Montserrat|Quicksand&display=swap net::ERR_FAILED
看来我也需要在 connect-src
下声明 google 字体。我没有在任何地方看到它(而且我 googled 很多)所以我想知道这是一个错误还是我确实需要在 connect-src
CSP 指令中定义字体?
connect-src 'fonts.googleapis.com'
将是必需的,尽管您当前 Content-Security-Policy。如果我可以用您没有特别要求的额外 material 来回答这个问题:
CSP 的目的是安全;为 style-src 设置 unsafe-inline 是不安全的。来自 MDN 专用于 style-src - https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/style-src :
的页面
Note: Disallowing inline styles and inline scripts is one of the biggest security wins CSP provides. However, if you absolutely have to use it, there are a few mechanisms that will allow them.
仅关注这一点,Google 的字体不能很好地与可以解决安全问题的 SRI(子资源完整性)配合使用。如果安全是需要尊重的东西,一个更好的选择是严格为您的字体使用辅助服务器(除非您选择实现 SRI-friendly 从 CDNJS 加载的网络字体)。这将允许您使用 google 字体实现散列,只需确保在 SERVER 和字体服务器之间具有正确的 CORS 设置。我还强烈建议将您的 default-src 锁定为 'none' ,然后按照 MDN 此处的详细说明定义以下每个提取指令: https://developer.mozilla.org/en-US/docs/Glossary/Fetch_directive ,一定不要使用 unsafe-inline在 script-src OR style-src 中,同时避免 unsafe-eval。 frame-ancestors 'none'
、upgrade-insecure-requests
(以及 block-all-mixed-content
任何使用 I.E. 或 Edge 的人)如果您决定实施 SRI,require-sri-for script style
.
我希望我没有夸大我的回答,当然,它对你有帮助。
我有一个渐进式网络应用程序。我正在使用 Google 字体,并且在我的 service worker 中使用 workbox。
我的内容安全策略定义为:
// Omitting all the other directives
style-src 'self' https://fonts.googleapis.com 'unsafe-inline';
font-src 'self' https://fonts.gstatic.com;
connect-src 'self';
我已经按照配方 here 设置了工作箱来缓存字体。代码如下:
workbox.routing.registerRoute(
/^https:\/\/fonts\.googleapis\.com/,
new workbox.strategies.StaleWhileRevalidate({
cacheName: 'google-fonts-stylesheets',
})
);
workbox.routing.registerRoute(
/^https:\/\/fonts\.gstatic\.com/,
new workbox.strategies.CacheFirst({
cacheName: 'google-fonts-webfonts',
plugins: [
new workbox.cacheableResponse.Plugin({
statuses: [0, 200],
}),
new workbox.expiration.Plugin({
maxAgeSeconds: 60 * 60 * 24 * 365,
maxEntries: 30,
}),
],
})
);
这里的问题是,当我尝试在浏览器 (Google Chrome / Safari) 或独立应用程序中加载我的应用程序时,字体不会加载。纠结了好久,Chrome 终于在控制台报错了:
Refused to connect to 'https://fonts.googleapis.com/css?family=Montserrat|Quicksand&display=swap' because it violates the following Content Security Policy directive: "connect-src 'self'".
Uncaught (in promise) no-response: no-response :: [{"url":"https://fonts.googleapis.com/css?family=Montserrat|Quicksand&display=swap","error":{}}]
at o.makeRequest (https://storage.googleapis.com/workbox-cdn/releases/4.2.0/workbox-strategies.prod.js:1:3983)
GET https://fonts.googleapis.com/css?family=Montserrat|Quicksand&display=swap net::ERR_FAILED
看来我也需要在 connect-src
下声明 google 字体。我没有在任何地方看到它(而且我 googled 很多)所以我想知道这是一个错误还是我确实需要在 connect-src
CSP 指令中定义字体?
connect-src 'fonts.googleapis.com'
将是必需的,尽管您当前 Content-Security-Policy。如果我可以用您没有特别要求的额外 material 来回答这个问题:
CSP 的目的是安全;为 style-src 设置 unsafe-inline 是不安全的。来自 MDN 专用于 style-src - https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/style-src :
Note: Disallowing inline styles and inline scripts is one of the biggest security wins CSP provides. However, if you absolutely have to use it, there are a few mechanisms that will allow them.
仅关注这一点,Google 的字体不能很好地与可以解决安全问题的 SRI(子资源完整性)配合使用。如果安全是需要尊重的东西,一个更好的选择是严格为您的字体使用辅助服务器(除非您选择实现 SRI-friendly 从 CDNJS 加载的网络字体)。这将允许您使用 google 字体实现散列,只需确保在 SERVER 和字体服务器之间具有正确的 CORS 设置。我还强烈建议将您的 default-src 锁定为 'none' ,然后按照 MDN 此处的详细说明定义以下每个提取指令: https://developer.mozilla.org/en-US/docs/Glossary/Fetch_directive ,一定不要使用 unsafe-inline在 script-src OR style-src 中,同时避免 unsafe-eval。 frame-ancestors 'none'
、upgrade-insecure-requests
(以及 block-all-mixed-content
任何使用 I.E. 或 Edge 的人)如果您决定实施 SRI,require-sri-for script style
.
我希望我没有夸大我的回答,当然,它对你有帮助。