【问题标题】:SVG stacking, anchor elements, and HTTP fetchingSVG 堆叠、锚元素和 HTTP 获取
【发布时间】:2015-02-20 21:40:59
【问题描述】:

我有一系列重叠的问题,最好将它们的交集问为:

<a href<img src 的上下文中,URL 中的# 字符(锚点)在什么情况下会触发HTTP 提取?

通常应该:

http://foo.com/bar.html#1

http://foo.com/bar.html#2

需要两个不同的 HTTP 提取?我认为答案肯定是否定的。

更具体的细节:

引发这个问题的情况是我第一次尝试使用SVG stacking——一种可以在单个svg 文件中嵌入多个图标的技术,因此只需要一个HTTP 请求。本质上,这个想法是将多个 SVG 图标放在一个文件中,并使用 CSS 隐藏所有图标,使用 CSS :target 选择器选择的图标除外。

然后,当您在 HTML 中编写 img 元素时,您可以使用 URL 中的 # 字符选择单个图标:

<img 
    src="stacked-icons.svg#icon3" 
    width="80" 
    height="60" 
    alt="SVG Stacked Image" 
/>

当我在 Chrome 上试用它时,它运行良好。发出单个 HTTP 请求,并且可以通过相同的 svg url 显示多个图标,使用不同的锚点/目标。

但是,当我使用 Firefox (28) 尝试此操作时,我通过控制台看到发出了 多个 HTTP 请求 - 每个 svg URL 一个!所以我看到的是这样的:

GET http://myhost.com/img/stacked-icons.svg#icon1 
GET http://myhost.com/img/stacked-icons.svg#icon2 
GET http://myhost.com/img/stacked-icons.svg#icon3 
GET http://myhost.com/img/stacked-icons.svg#icon4
GET http://myhost.com/img/stacked-icons.svg#icon5

...这当然违背了首先使用 SVG 堆叠的目的。

Firefox 是否有某种原因为 每个 URL 发出单独的 HTTP 请求,而不是像 Chrome 那样简单地获取 img/stacked-icons.svg 一次?

这就引出了一个更广泛的问题——哪些规则决定 URL 中的 # 字符是否应该触发 HTTP 请求?

【问题讨论】:

  • 这听起来像一个错误 - 从服务器的角度来看,# 后面的部分完全没有兴趣,甚至不能保证提交给服务器。也许你应该提交一个错误here,特别是因为 Chrome 以预期的方式工作(所以它与 svg 本身无关)。
  • 您的缓存可能有问题。如果您禁用资源缓存(例如通过 apache/iis/etc.config),某些浏览器将继续获取资源。如果您可以使用有关 Chrome/Firefox 响应的更多详细信息更新您的问题,那将很有帮助。
  • 我在 FF34 中测试时收到一个请求。并且片段不应随请求一起发送。
  • 你可以使用 css sprites

标签: html css http svg


【解决方案1】:

这是 Plunker 中的一个演示,可帮助解决其中的一些问题

URI 有几个基本组成部分:

  • 协议 - 确定如何发送请求
  • - 发送请求的位置
  • 位置 - 域内的文件路径
  • 片段 - 要查看文档的哪个部分

媒体片段 URI

片段只是识别整个文件的一部分。

根据Media Fragment URI spec 的实现,浏览器发送片段标识符实际上可能是完全公平的游戏。考虑一个流式视频,其中一些已缓存在客户端上。如果请求是针对/video.ogv<b>#t=10,20</b>,那么服务器可以通过只发回相关部分/段/片段来节省空间。此外,如果媒体的适用部分已经缓存在客户端,则浏览器可以阻止往返。

考虑往返,而不是请求

当浏览器发出 GET 请求时,并不一定意味着它需要从服务器一路抓取文件的新副本。如果已经有缓存版本,可以立即响应请求。

HTTP 状态码

  • 200 - OK - 获取资源并从服务器返回
  • 302 - Found - 在缓存中找到资源,但自上次请求以来我们需要获取新副本的资源并没有发生足够的变化。

缓存禁用

各种因素都会影响客户端是否执行缓存:发出请求的方式(F5 - 软刷新;Ctrl + R kbd> - 硬刷新)、浏览器上的设置、向请求添加属性的任何开发工具,以及服务器处理这些属性的方式。通常,当浏览器的开发工具打开时,它会自动禁用缓存,以便您可以轻松测试对文件的更改。如果您正在尝试专门观察缓存行为,请确保您没有任何干扰此行为的开发人员设置。

在跨浏览器比较请求时,为了帮助减少开发者工具 UI 之间的差异,您应该使用像 fiddler 这样的工具来检查通过网络发出的实际 HTTP 请求和响应。我将向您展示简单的 plunker 示例。当页面加载时,它应该在同一个堆叠的 svg 文件中请求两个不同的 id。

这里是side by side requests of the same test page in Chrome 39, FF 34, and IE 11:


启用缓存

但我们想测试在启用缓存的普通客户端上会发生什么。为此,请为每个浏览器更新您的开发工具,或者转到 fiddler 和 Rules > Performance > 并取消选中 Disable Caching

现在我们的请求应该是这样的:

现在所有文件都从本地缓存返回,不管片段 ID 是什么

特定浏览器的开发者工具可能会为了您自己的利益而尝试显示片段 ID,但提琴手应始终显示实际请求的最准确地址。我测试的每个浏览器都从请求中省略了地址的片段部分:

捆绑请求

有趣的是,chrome 似乎足够聪明,可以防止对同一资源的第二次请求,但是当片段是地址的一部分时,FF 和 IE 无法做到这一点。这同样适用于 SVG 和 PNG。因此,第一次请求页面时,每次实际使用 SVG 堆栈时,浏览器都会加载一个文件。此后,很高兴从缓存中获取版本,但会损害新观众的性能。

最终成绩

CONFirst Trip - 并非所有浏览器都完全支持 SVG 堆栈。每个实例发出一个请求。
PRO第二次旅行 - SVG 资源将被适当缓存

其他资源

错误

通常,为页面请求的相同资源将被捆绑到单个请求中,该请求将满足所有请求元素。 Chrome 似乎已经修复了这个问题,但我已经打开了 FF 和 IE 的错误,希望有一天能解决这个问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-11-18
    • 2016-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-05
    相关资源
    最近更新 更多