从昨天开始,我已经注意到了我的博客图标显示有问题,我以为是浏览器的问题,就没多理会,然后我发现我朋友的博客也出现了这个问题,我问他他那边显示有问题不,他说有,然后我才想着解决这个问题。
就像这样:
所有关于fontawesome
的图标都沦陷了。
一开始,我以为是从url引入的fontawesome
包有网络问题,但是我单独打开这个url是可以直接打开的(https://cdn.staticfile.org/font-awesome/6.4.2/css/all.min.css)这也是主题作者用的包,位于layout
文件夹下的import.ejs
文件中的前几行。
后来我又了解到要想使fontawesome
的all.min.css
能正常加载,正常显示图标,必须得引入对应包下的fonts
文件夹,我转而想到,有可能是作者cdn中的webfonts
包不能正常加载。
我第一个想到的办法是:
将整个
fontawesome
包放在博客仓库下。
这很简单,这样解决:
从
fontawesome
官网下载对应的web包。(6.5.1)修改一下文件名
fontawesome6.5.1
,复制到到博客主题下的source
目录。打开主题目录下的
layout
文件夹,修改其中的import.ejs
文件,找到第三行:<link rel="stylesheet" href="https://cdn.staticfile.org/font-awesome/6.4.2/css/all.min.css" />
修改为:
<link rel="stylesheet" href="/fontawesome6.5.1/css/all.min.css" />
这将从博客的根目录下查找这个文件,因为放到source文件夹下的文件,被渲染后将放在博客仓库的根目录下。
hexo g,hexo d。
但是我很快发现了这样解决的问题,从根目录下搜寻文件很浪费性能,导致加载速度很慢,直接的结果就是,我的博客加载速度长了一两秒。
这我肯定是不能满意的,于是我想到像图床一样,在netlify
再建一个仓库,将fontawesome
包放进去,然后通过url引入到我的博客中。
可是我遇到了很奇怪的事情,我试了很多次,最后还是加载异常,我甚至很玄学的把all.min.css
文件放在二级目录下,因为作者的url就是这样的结构,但还是不行,我测试了我这个仓库的全国延迟:
我把图标显示异常的原因归结于netlify
的不给力,但是我单独在浏览器中访问该仓库的url,是能够正常显示all.min.css
的内容的,我还检查了all.min.css
的最后几行引入webfonts
的代码(这是压缩过的,显得很拥挤):
font-display:block;src:url(../webfonts/fa-regular-400.woff2) format("woff2"),url(../webfonts/fa-regular-400.ttf) format("truetype")}.fa-regular,.far{font-weight:400}:host,:root{--fa-style-family-classic:"Font Awesome 6 Free";--fa-font-solid:normal 900 1em/1 "Font Awesome 6 Free"}@font-face{font-family:"Font Awesome 6 Free";font-style:normal;font-weight:900;font-display:block;src:url(../webfonts/fa-solid-900.woff2) format("woff2"),url(../webfonts/fa-solid-900.ttf) format("truetype")}.fa-solid,.fas{font-weight:900}@font-face{font-family:"Font Awesome 5 Brands";font-display:block;font-weight:400;src:url(../webfonts/fa-brands-400.woff2) format("woff2"),url(../webfonts/fa-brands-400.ttf) format("truetype")}@font-face{font-family:"Font Awesome 5 Free";font-display:block;font-weight:900;src:url(../webfonts/fa-solid-900.woff2) format("woff2"),url(../webfonts/fa-solid-900.ttf) format("truetype")}@font-face{font-family:"Font Awesome 5 Free";font-display:block;font-weight:400;src:url(../webfonts/fa-regular-400.woff2) format("woff2"),url(../webfonts/fa-regular-400.ttf) format("truetype")}@font-face{font-family:"FontAwesome";font-display:block;src:url(../webfonts/fa-solid-900.woff2) format("woff2"),url(../webfonts/fa-solid-900.ttf) format("truetype")}@font-face{font-family:"FontAwesome";font-display:block;src:url(../webfonts/fa-brands-400.woff2) format("woff2"),url(../webfonts/fa-brands-400.ttf) format("truetype")}@font-face{font-family:"FontAwesome";font-display:block;src:url(../webfonts/fa-regular-400.woff2) format("woff2"),url(../webfonts/fa-regular-400.ttf) format("truetype");unicode-range:u+f003,u+f006,u+f014,u+f016-f017,u+f01a-f01b,u+f01d,u+f022,u+f03e,u+f044,u+f046,u+f05c-f05d,u+f06e,u+f070,u+f087-f088,u+f08a,u+f094,u+f096-f097,u+f09d,u+f0a0,u+f0a2,u+f0a4-f0a7,u+f0c5,u+f0c7,u+f0e5-f0e6,u+f0eb,u+f0f6-f0f8,u+f10c,u+f114-f115,u+f118-f11a,u+f11c-f11d,u+f133,u+f147,u+f14e,u+f150-f152,u+f185-f186,u+f18e,u+f190-f192,u+f196,u+f1c1-f1c9,u+f1d9,u+f1db,u+f1e3,u+f1ea,u+f1f7,u+f1f9,u+f20a,u+f247-f248,u+f24a,u+f24d,u+f255-f25b,u+f25d,u+f271-f274,u+f278,u+f27b,u+f28c,u+f28e,u+f29c,u+f2b5,u+f2b7,u+f2ba,u+f2bc,u+f2be,u+f2c0-f2c1,u+f2c3,u+f2d0,u+f2d2,u+f2d4,u+f2dc}@font-face{font-family:"FontAwesome";font-display:block;src:url(../webfonts/fa-v4compatibility.woff2) format("woff2"),url(../webfonts/fa-v4compatibility.ttf)
但是是没有问题的,都是通过相对路径的方式../webfonts
,只要我正常引入整个fontawesome
包,肯定是不影响webfonts
的引入的,这让我很头大,我只能把问题归结于网络。
于是,我尝试了理论上不存在网络问题的阿里云OSS
,我把fontawesome
放入一个bucket
中,还绑了一个域名,甚至把权限改为了公共读写
,但是问题依然没有得到解决,于是,我暂时放弃了这个方法。
我想到了另外一种方法:
使用其他cdn下的
fontawesome
。
全国延迟测试:
- 使用官方的FontAwesome CDN:https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css
全国延迟测试:
感觉差不多,但是距离原作者的cdn:
还是差距有点大。
我是不满意的,但是没办法,我还是对自建仓库的方案耿耿于怀,为啥不能正常加载?
我突然想到可以查看一下浏览器控制台的输出,有什么报错。(我之前一直没有看浏览器后台的习惯!!!)
然后我发现了新大陆:
Access to font at 'https://cdn.staticfile.org/font-awesome/6.4.2/webfonts/fa-solid-900.woff2' from origin 'http://localhost:4000' has been blocked by CORS policy: The 'Access-Control-Allow-Origin' header has a value 'https://www.pil0txia.com' that is not equal to the supplied origin.
fa-solid-900.woff2:1 Failed to load resource: net::ERR_FAILED
localhost/:1 Access to font at 'https://cdn.staticfile.org/font-awesome/6.4.2/webfonts/fa-brands-400.woff2' from origin 'http://localhost:4000' has been blocked by CORS policy: The 'Access-Control-Allow-Origin' header has a value 'https://www.mikuclub.win' that is not equal to the supplied origin.
fa-brands-400.woff2:1 Failed to load resource: net::ERR_FAILED
VM25:1 [Deprecation] 'window.webkitStorageInfo' is deprecated. Please use 'navigator.webkitTemporaryStorage' or 'navigator.webkitPersistentStorage' instead.
V @ VM25:1
fireworks.min.js:1 Uncaught ReferenceError: anime is not defined
at fireworks.min.js:1
at fireworks.min.js:1
localhost/:1 Access to font at 'https://cdn.staticfile.org/font-awesome/6.4.2/webfonts/fa-solid-900.ttf' from origin 'http://localhost:4000' has been blocked by CORS policy: The 'Access-Control-Allow-Origin' header has a value 'https://www.mikuclub.win' that is not equal to the supplied origin.
fa-solid-900.ttf:1 Failed to load resource: net::ERR_FAILED
localhost/:1 Access to font at 'https://cdn.staticfile.org/font-awesome/6.4.2/webfonts/fa-brands-400.ttf' from origin 'http://localhost:4000' has been blocked by CORS policy: The 'Access-Control-Allow-Origin' header has a value 'https://www.mikuclub.win' that is not equal to the supplied origin.
fa-brands-400.ttf:1 Failed to load resource: net::ERR_FAILED
content.js:30 Uncaught DOMException: Failed to execute 'getRangeAt' on 'Selection': 0 is not a valid index.
at HTMLDocument.checkContextMenuInSelection (chrome-extension://hgploeanmefhfpokeenldbnhbnmnlplj/scripts/content.js:30:33)
一直频繁出现的一个词
CORS
,不禁好奇,什么是CORS
?
CORS(Cross-Origin Resource Sharing)是一种浏览器安全策略,用于控制在不同源(Origin)之间进行的Web页面间的资源共享。同源策略是一种浏览器安全机制,阻止网页从一个源加载的脚本或资源与来自另一个源的文档进行交互。
CORS通过在HTTP请求和响应头中添加一些额外的信息来允许或拒绝跨域请求。例如,当从一个域的网页尝试请求另一个域的资源时,目标服务器可以通过在响应头中包含正确的 Access-Control-Allow-Origin
值来允许请求,否则浏览器将阻止该请求。
简而言之,CORS允许服务器声明哪些域有权限访问其资源,以增加Web应用程序的安全性。
就是说在我的域名下,访问了不属于我域名下的资源,被浏览器禁止了,那,怎么解决呢?
解决这个问题的方法有两个:
1. 配置CDN服务器支持CORS
如果您有权访问CDN服务器(https://cdn.staticfile.org
),您可以在CDN服务器上配置CORS规则,以允许来自特定域的跨域请求。在CDN服务器上的配置文件中添加以下头部:
<AccessControlAllowOrigin>你的域名</AccessControlAllowOrigin>
请确保将 <AccessControlAllowOrigin>
的值设置为您的Netlify域名。
2. 使用支持CORS的CDN或其他服务
如果您无法直接配置CDN服务器,可以考虑使用已经配置了CORS的CDN服务,或者使用支持CORS的其他服务。
例如,您可以考虑使用官方的FontAwesome CDN(刚才已经用过):
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css" integrity="sha512-..." crossorigin="anonymous" />
在这种情况下,crossorigin="anonymous"
表示使用匿名身份验证,而不会发送用户的凭据(例如cookie)。
总的来说,解决问题的关键是确保字体资源的响应头中包含了正确的 Access-Control-Allow-Origin
头部,并且与请求的域名匹配。
但是我显然无法控制原作者的cdn,那怎么办?
1. 使用代理
您可以在自己的服务器上设置一个代理,通过代理来获取字体文件。这个代理服务器可以将来自 https://cdn.staticfile.org
的请求转发到原始服务器,并将响应返回给您的网页。这样,由于请求是从您的域发出的,就避免了浏览器的同源策略和CORS问题。
代理服务器的实现
您可以使用Node.js、Express等构建一个简单的代理服务器。以下是一个基本的示例:
1.安装 Node.js 和 Express(如果尚未安装):
npm install express
2.创建一个代理服务器脚本(proxy.js):
econst express = require('express');
const { createProxyMiddleware } = require('http-proxy-middleware');
const app = express();
app.use('/font-awesome', createProxyMiddleware({
target: 'https://cdn.staticfile.org',
changeOrigin: true,
pathRewrite: { '^/font-awesome': '/' },
}));
const PORT = 3000;
app.listen(PORT, () => {
console.log(`Proxy server is running on port ${PORT}`);
});
3.运行代理服务器:
node proxy.js
4.在您的网页中,将字体文件的请求路径修改为代理服务器的路径:
<link rel="stylesheet" href="https://cdn.staticfile.org/font-awesome/6.4.2/css/all.min.css">
修改为:
<link rel="stylesheet" href="你的域名/font-awesome/6.4.2/css/all.min.css">
当然我们这里需要修改ejs文件中的url。
2. 使用CORS代理服务
您还可以考虑使用一些提供CORS代理服务的第三方工具。这些服务允许您通过它们的服务器发起请求,然后它们将请求转发给原始服务器,并将响应返回给您的网页。这样,您的网页就可以绕过同源策略和CORS问题。
一些常见的CORS代理服务包括:
在使用这些服务时,请确保了解服务的使用规定,并注意它们的可靠性和安全性。
总体而言,这些方法是绕过同源策略和CORS问题的替代方案。请注意,使用代理可能会导致一些性能和安全方面的考虑,因此请谨慎使用。
那如果我使用自己的仓库呢,不使用cdn呢?
如果您的FontAwesome资源托管在Netlify上,而且您在使用它们的过程中遇到了CORS问题,可以尝试以下方法解决:
1. Netlify配置文件 _headers
在您的Netlify项目的根目录下创建一个名为 _headers
的文件,并添加如下内容:
mathematica/*
Access-Control-Allow-Origin: *
这将在所有资源的响应中添加 Access-Control-Allow-Origin
头,允许任何域访问资源。请注意,这可能会导致一些安全性问题,因为它允许所有域访问资源。如果安全性是关键问题,请考虑将 *
替换为您允许的域。
2. Netlify Functions
如果您的FontAwesome资源是通过Netlify函数(Netlify Functions)提供的,您可以在函数中设置CORS头。以下是一个示例函数:
exports.handler = async function(event, context) {
return {
statusCode: 200,
headers: {
'Access-Control-Allow-Origin': '*',
// Add other necessary headers
},
body: JSON.stringify({ message: 'Hello World' }),
};
};
此函数会返回包含 Access-Control-Allow-Origin
头的响应。确保在您的Netlify函数中添加这个头,以允许跨域访问。
3. Netlify配置文件 netlify.toml
如果您的项目有 netlify.toml
配置文件,您可以尝试在其中添加如下配置:
[[headers]]
for = "/*"
[headers.values]
Access-Control-Allow-Origin = "*"
这会设置所有路径的 Access-Control-Allow-Origin
头,允许任何域访问资源。
请注意,这些方法都是基于假设您具有对Netlify项目的足够控制权。如果FontAwesome资源是由其他服务提供的,您可能需要查看该服务的文档或联系其支持团队,以获取关于如何处理CORS问题的更多信息。
我给仓库添加了_headers
文件,然后打开了浏览器在本地测试,居然还是显示异常,别沮丧,继续查看控制台:
VM26:1 [Deprecation] 'window.webkitStorageInfo' is deprecated. Please use 'navigator.webkitTemporaryStorage' or 'navigator.webkitPersistentStorage' instead.
V @ VM26:1
fireworks.min.js:1 Uncaught ReferenceError: anime is not defined
at fireworks.min.js:1
at fireworks.min.js:1
12Failed to decode downloaded font: <URL>
localhost/:1 Failed to decode downloaded font: https://tianapi.netlify.app/fontawesome/fontawesome6.5.1/webfonts/fa-solid-900.woff2
localhost/:1 Failed to decode downloaded font: https://tianapi.netlify.app/fontawesome/fontawesome6.5.1/webfonts/fa-solid-900.woff2
localhost/:1 Failed to decode downloaded font: https://tianapi.netlify.app/fontawesome/fontawesome6.5.1/webfonts/fa-solid-900.woff2
localhost/:1 Failed to decode downloaded font: https://tianapi.netlify.app/fontawesome/fontawesome6.5.1/webfonts/fa-brands-400.woff2
localhost/:1 Failed to decode downloaded font: https://tianapi.netlify.app/fontawesome/fontawesome6.5.1/webfonts/fa-brands-400.woff2
localhost/:1 Failed to decode downloaded font: https://tianapi.netlify.app/fontawesome/fontawesome6.5.1/webfonts/fa-brands-400.woff2
localhost/:1 Failed to decode downloaded font: https://tianapi.netlify.app/fontawesome/fontawesome6.5.1/webfonts/fa-solid-900.ttf
localhost/:1 Failed to decode downloaded font: https://tianapi.netlify.app/fontawesome/fontawesome6.5.1/webfonts/fa-solid-900.ttf
localhost/:1 Failed to decode downloaded font: https://tianapi.netlify.app/fontawesome/fontawesome6.5.1/webfonts/fa-solid-900.ttf
localhost/:1 Failed to decode downloaded font: https://tianapi.netlify.app/fontawesome/fontawesome6.5.1/webfonts/fa-brands-400.ttf
localhost/:1 Failed to decode downloaded font: https://tianapi.netlify.app/fontawesome/fontawesome6.5.1/webfonts/fa-brands-400.ttf
localhost/:1 Failed to decode downloaded font: https://tianapi.netlify.app/fontawesome/fontawesome6.5.1/webfonts/fa-brands-400.ttf
6OTS parsing error: Failed to convert WOFF 2.0 font to SFNT
localhost/:1 OTS parsing error: Failed to convert WOFF 2.0 font to SFNT
localhost/:1 OTS parsing error: Failed to convert WOFF 2.0 font to SFNT
localhost/:1 OTS parsing error: Failed to convert WOFF 2.0 font to SFNT
localhost/:1 OTS parsing error: Failed to convert WOFF 2.0 font to SFNT
localhost/:1 OTS parsing error: Failed to convert WOFF 2.0 font to SFNT
localhost/:1 OTS parsing error: Failed to convert WOFF 2.0 font to SFNT
localhost/:1 OTS parsing error: cmap: invalid table offset
localhost/:1 OTS parsing error: cmap: invalid table offset
localhost/:1 OTS parsing error: cmap: invalid table offset
localhost/:1 OTS parsing error: cmap: table overruns end of file
localhost/:1 OTS parsing error: cmap: table overruns end of file
localhost/:1 OTS parsing error: cmap: table overruns end of file
content.js:30 Uncaught DOMException: Failed to execute 'getRangeAt' on 'Selection': 0 is not a valid index.
at HTMLDocument.checkContextMenuInSelection (chrome-extension://hgploeanmefhfpokeenldbnhbnmnlplj/scripts/content.js:30:33)
这回报错变了,这个问题通常是由于字体文件的 MIME 类型未正确设置导致的。浏览器在下载字体文件时,会根据其 MIME 类型(例如,application/font-woff2
或 application/x-font-ttf
)来解析和呈现字体。如果服务器未正确设置字体文件的 MIME 类型,浏览器可能无法正确解析字体文件,从而导致“Failed to decode downloaded font”错误。
有可能是浏览器的缓存没清理,于是我清理了缓存,终于,成功了!!!!!
ohohohoh!!!
至此,已成艺术,真的很激动,哈哈哈哈。
这次经历让我养成了查看浏览器控制台的习惯,要从问题根源下手。