可以使用 Link HTTP header 或仅使用 <link> 标签指定 HTML 导入吗?

Can HTML imports be specified using the Link HTTP header, or only with a <link> tag?

HTML <link> 元素最常用于在文档中包含 CSS 样式表。典型的用法可能如下所示:

<link rel="stylesheet" href="/style.css" />

作为在响应 body 中包含标记的替代方法,服务器可以使用 Link HTTP header 指定样式表:

HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Link: </style.css>; rel=stylesheet

<!doctype html>
<html>
  <head><title>Example</title></head>
  <body>Hello!</body>
</html>

提议的 HTML 导入功能规范 (WC3 working draft) 向 <link> 元素添加了一个重要的新功能:从另一个 [=45= 导入所有资源的能力] 文档,可能包括多个脚本、样式和模板。典型的用法可能如下所示:

<link rel="import" href="/components.html" />

我的期望是也可以使用 Link header 以与样式相同的方式指定 HTML 导入,对于这样的情况:

HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Link: </components.html>; rel=import

<!doctype html>
<html>
  <head><title>Example</title></head>
  <body><ex-warm-welcome>Hello!</ex-warm-welcome></body>
</html>

然而,工作草案规范仅明确提及 <link> 元素;它没有引用 Link header。它还使用似乎需要 <link> 元素与每个导入关联的语言,

Each document has an import link list, each of whose item is consist of link, the link element and location, a URL.

我看到 <link rel="import" ... /> 支持样式表链接不支持的 async 属性。不可能在 header 中指定它,但考虑到它是一个可选属性,我不希望这会完全阻止它的支持。

是否可以使用 Link header 指定 HTML 导入?

没有

根据 RFC 5988: Web LinkingLink header 在语义上应该等同于 <link> 元素:

5.  The Link Header Field

   The Link entity-header field provides a means for serialising one or
   more links in HTTP headers.  It is semantically equivalent to the
   <LINK> element in HTML, as well as the atom:link feed-level element
   in Atom [RFC4287].

然而,HTML5 规范 (W3C recommendation) 的“link 元素”部分似乎与此矛盾,明确表示允许它们的语义不同:

HTTP Link: headers, if supported, must be assumed to come before any links in the document, in the order that they were given in the HTTP message. These headers are to be processed according to the rules given in the relevant specifications. [HTTP] [WEBLINK]

Note: Registration of relation types in HTTP Link: headers is distinct from HTML link types, and thus their semantics can be different from same-named HTML types.

RFC 5988 只是一个“提议的标准”(info on rfc-editor.org),尽管它被 HTML5 规范引用,但引用被明确标记为“non-normative”。它仅引用 HTML4 规范本身。鉴于 HTML5 规范是一个完整的标准并且更新,我希望它比 RFC 更相关,并且不希望 Link header 在这种情况下起作用。但是让我们暂时搁置所有这些律师并实际测试它。

这是一个简单的节点服务器,提供试图以各种方式指定 HTML 导入的页面:

require('http').createServer(function(request, response) {
  switch (request.url) {
    case '/inline.html':
      response.writeHead(200, {
        'Content-Type': 'text/html',
      });
      response.write('<!doctype html><html><head>');
      response.write('<link rel="import" href="/import.html" />');
      break;

    case '/header.html':
      response.writeHead(200, {
        'Content-Type': 'text/html',
        'Link': '</import.html>; rel=import'
      });
      response.write('<!doctype html><html><head>');
      break;

    case '/import.html':
      response.writeHead(200, {
        'Content-Type': 'text/html',
      });
      response.write('<!doctype html><html><head>');
      response.write('<script>console.log("imported!")</script>');
      break;

    default:
      response.writeHead(404);
  }

  response.end();
}).listen(8080);

当我访问 Chrome 中的 /inline.html 时,我看到“已导入!”按预期登录控制台。但是当我访问 /header.html 时,我什么也没看到。所以最终的答案似乎是 :规范和实现都不支持在 Link header 中声明 HTML 导入。

健全性检查揭示了这个测试的一个非常错误的前提:Chrome currently doesn't even support the Link header for stylesheets!它是目前唯一支持 HTML 默认导入的浏览器引擎,所以我们的结论仍然是正确的,但测试本身并没有真正说明预期的行为,因为无论如何它肯定会失败。