最近想在 markdown 里搞图文混排,遇到一个大图把版面占完了,想缩小一些,由于 .md 渲染器安全限制,没法直接指定宽高

只能从图片本身想办法,首先最直接的手段就是服务器再缩放一次,但是蛋痛的问题是缩放之后文件怎么存,怎么给静态文件路由,怎么保障图片可用性,怎么兼容各种尺寸,想想都头大。

想到一个 hack,要不直接放一个 .svg 进去,因为 svg 支持加载位图资源,所以把 svg 位图缩小一点,让浏览器渲染 svg 不就行了。

没想到就被这个 hack 坑了。原因是 svg 如果被 <img> 标签渲染,那么禁止加载任何外部资源,脚本也禁止执行。

为了证明这个限制,我写了个 demo 放在 https://lab.est.im/shit_svg/

这个问题太隐蔽了。stackoverflow 上只有 Robert LongsonThangLeQuocTheHippo
的答案提到隐约线索:

后来搜了到 skychx 把这个问题研究透了。罪魁祸首 SVG Security

If an SVG file is fetched as image, then certain requirements apply to this document:

  • The SVG document is not allowed to fetch any resources. This also applies to scripts, stylesheets or images.
  • Fonts shouldn't be loaded as well. The situation in UAs seems to still be unclear though.
    Scripts must not be executed.
  • Event listeners must be disabled at all times.

浪费我好多时间。SVG2里把这个说得很明白了 https://www.w3.org/TR/SVG2/conform.html#processing-modes

When external references are disabled in an SVG document, any attempt to fetch a document through an external reference must instead be treated as if a network error occurred and no data was received.

不过查阅资料的时候发现个好玩的,SVG 1.1 支持 URL fragments

比如: