使用html-to-image导出HTML的Div为SVG时字体失效及CORS问题求助
解决html-to-image导出SVG时的字体显示与CORS问题
先解决CORS错误
你碰到的CORS报错是因为直接用file://协议打开本地HTML文件,浏览器出于安全限制,不允许这种协议下的跨域请求(包括加载本地字体文件)。解决方法很简单:
- 启动一个本地HTTP服务器来访问你的文件,比如:
- 用Python:在文件目录下运行
python -m http.server 8000,然后访问http://localhost:8000/你的文件名.html - 用VSCode的Live Server插件,右键选择"Open with Live Server"
- 用Node.js的http-server:先安装
npm install -g http-server,然后运行http-server,访问对应的地址
- 用Python:在文件目录下运行
处理字体不显示的问题
html-to-image导出SVG时,要确保字体被正确加载并嵌入到SVG中,有两种可靠的方式:
方法1:将字体转为Data URI嵌入CSS
把本地的Raleway-Medium.ttf转成base64编码,直接写在CSS里,这样不需要外部文件,也能避免加载问题。
可以用在线工具或者本地命令行生成base64(比如base64 Raleway-Medium.ttf),然后修改@font-face:
@font-face { font-family: Raleway; src: url(data:font/truetype;base64,这里替换成你的字体base64编码) format('truetype'); font-weight: 500; font-style: normal; }
方法2:等待字体加载完成后再导出
浏览器加载字体需要时间,如果在字体没加载完就调用导出,会用默认字体替代。可以用document.fonts.ready来等待字体加载完成,修改你的JS代码:
function filter(node) { return (node.tagName !== 'i'); } // 等待字体加载完成再执行导出 document.fonts.ready.then(() => { htmlToImage.toSvg(document.getElementById('my-node'), {filter: filter}) .then(function (dataUrl) { let svg = decodeURIComponent(dataUrl.split(',')[1]) console.log(svg); }); });
修改后的完整代码示例
<head> <style> @font-face { font-family: Raleway; <!-- 这里替换成你生成的Data URI --> src: url(data:font/truetype;base64,ABCDEF...) format('truetype'); font-weight: 500; font-style: normal; } #my-node { font-family: "Raleway"; } .myDiv { padding: 2px; border: 1px solid #bebdbd; } .myText { font-size: 15px; letter-spacing: 0.02em; font-weight: 500; } </style> </head> <body> <div id="my-node"> <div class="myDiv" style="top: 100px; left: 100px;"> <span class="myText">Here is some text</span> </div> </div> <script src="https://cdnjs.cloudflare.com/ajax/libs/html-to-image/1.11.11/html-to-image.js"></script> <script type="text/javascript"> function filter(node) { return (node.tagName !== 'i'); } document.fonts.ready.then(() => { htmlToImage.toSvg(document.getElementById('my-node'), {filter: filter}) .then(function (dataUrl) { let svg = decodeURIComponent(dataUrl.split(',')[1]) console.log(svg); }); }); </script> </body>
内容的提问来源于stack exchange,提问作者AntonAntonoff
相关产品推荐
相关产品推荐

