我从未见过<base> HTML标签实际上在任何地方使用。它的使用是否存在意味着我应该避免使用的陷阱?

事实上,我从未注意到它在现代生产站点(或任何站点)上使用过,这让我对它持怀疑态度,尽管它似乎在简化我站点上的链接方面有有用的应用程序。


Edit

After using the base tag for a few weeks, I did end up finding some major gotchas with using the base tag that make it much less desirable than it first appeared. Essentially, the changes to href='#topic' and href='' under the base tag are very incompatible with their default behavior, and this change from the default behavior could easily make third party libraries outside of your control very unreliable in unexpected ways, since they will logically depend on the default behavior. Often the changes are subtle and lead to not-immediately-obvious problems when dealing with a large codebase. I have since created an answer detailing the issues that I experienced below. So test the link results for yourself before you commit to a widespread deployment of <base>, is my new advice!


当前回答

基本标签的效果分解:

base标记似乎有一些非直观的效果,我建议在依赖<base>!由于我是在尝试使用base标签来处理url不同的本地站点后发现它们的,并且在此之后才发现有问题的效果,令我沮丧的是,我觉得有必要为其他人创建这些潜在陷阱的摘要。

在下面的例子中,我将使用base标记:<base href="http://www.example.com/other-subdirectory/">作为示例,并将代码所在的页面假设为http://localsite.com/original-subdirectory

主要:

没有链接、命名锚或空白引用将指向原始子目录,除非显式: base标签使所有链接都不同,包括指向base标签url的同页锚链接,例如:

<a href='#top-of-page' title='Some title'>通过命名锚指向页面顶部的链接</a> 就变成了 <a href='http://www.example.com/other-subdirectory/#top-of-page' title='Some title'>一个链接到一个#命名锚在完全不同的基本页</a> < a href = ' ?update=1' title='Some title'>该页面的链接</ A > . update=1' title='Some title'> 就变成了 <a href='http://www.example.com/other-subdirectory/?update=1' title='Some title'>一个指向基本标签页面的链接

通过一些工作,您可以通过显式地指定这些链接链接到它们所在的页面来修复您所控制的链接上的这些问题,但是当您将依赖于标准行为的第三方库添加到组合中时,很容易造成很大的混乱。

小:

IE6修复了需要条件注释:需要条件注释的IE6,以避免搞砸dom层次结构,即<base href="http://www.example.com/"><!——[if lte IE 6]></base><![endif]- >正如BalusC在他上面的回答中提到的。

所以总的来说,主要的问题是使用棘手,除非你对每个链接都有完全的编辑控制,正如我最初担心的那样,这让它变得更麻烦。现在我不得不重新编写我对它的所有应用!: p

使用“片段”/散列时测试问题的相关链接:

http://www.w3.org/People/mimasa/test/base/

http://www.w3.org/People/mimasa/test/base/results


编辑:对于所有和我一样对评论感到困惑的人:

我自己刚刚进行了测试,结果如下:

尾斜杠与否,对这里给出的例子没有影响(#anchor和?query将简单地附加到指定的<BASE>)。 然而,对于相对链接来说,这是不同的:省略后面的斜杠,other.html和dir/other.html将从给定示例的DOCUMENT_ROOT开始,/other-子目录(正确地)被视为文件,因此省略。

因此,对于相对链接,BASE可以很好地用于移动的页面,而锚和?查询则需要显式指定文件名(BASE有一个尾随斜杠,或者最后一个元素不对应于它所使用的文件的名称)。

可以把它看作是<BASE>替换文件本身的完整URL(而不是文件所在的目录),这样您就会得到正确的结果。假设本例中使用的文件是other-subdirectory/test.html(在它移动到新位置之后),正确的规范应该是:

<基地href = " http://www.example.com/other-subdirectory/test.html " >

-等瞧,一切都按预期工作:#anchor, ?query, other.html, very/other.html, /completely/other.html。

其他回答

它使页面更容易离线查看;您可以将完全限定的URL放在基本标记中,然后您的远程资源将正常加载。

另外,你应该记住,如果你在非标准端口上运行你的web服务器,你也需要在base href上包含端口号:

<base href="//localhost:1234" />  // from base url
<base href="../" />  // for one step above

在决定是否使用<base>标记之前,您需要了解它是如何工作的,它可以用于什么以及它的含义是什么,并最终超过优点/缺点。


<base>标记主要简化了模板语言中相对链接的创建,因为您不需要担心每个链接中的当前上下文。

比如说

<base href="${host}/${context}/${language}/">
...
<link rel="stylesheet" href="css/style.css" />
<script src="js/script.js"></script>
...
<a href="home">home</a>
<a href="faq">faq</a>
<a href="contact">contact</a>
...
<img src="img/logo.png" />

而不是

<link rel="stylesheet" href="/${context}/${language}/css/style.css" />
<script src="/${context}/${language}/js/script.js"></script>
...
<a href="/${context}/${language}/home">home</a>
<a href="/${context}/${language}/faq">faq</a>
<a href="/${context}/${language}/contact">contact</a>
...
<img src="/${context}/${language}/img/logo.png" />

请注意,<base href>值以斜杠结束,否则它将相对于最后一个路径进行解释。


As to browser compatibility, this causes only problems in IE. The <base> tag is in HTML specified as not having an end tag </base>, so it's legit to just use <base> without an end tag. However IE6 thinks otherwise and the entire content after the <base> tag is in such case placed as child of the <base> element in the HTML DOM tree. This can cause at first sight unexplainable problems in Javascript/jQuery/CSS, i.e. the elements being completely unreachable in specific selectors like html>body, until you discover in the HTML DOM inspector that there should be a base (and head) in between.

一个常见的IE6修复是使用IE条件注释来包含结束标记:

<base href="http://example.com/en/"><!--[if lte IE 6]></base><![endif]-->

如果你不关心W3验证器,或者当你已经在HTML5上,那么你可以自我关闭它,每个web浏览器都支持它:

<base href="http://example.com/en/" />

关闭<base>标记还可以立即修复WinXP SP3上的IE6在无限循环中使用src中的相对URI请求<script>资源的疯狂问题。

Another potential IE problem will manifest when you use a relative URI in the <base> tag, such as <base href="//example.com/somefolder/"> or <base href="/somefolder/">. This will fail in IE6/7/8. This is however not exactly browser's fault; using relative URIs in the <base> tag is namely at its own wrong. The HTML4 specification stated that it should be an absolute URI, thus starting with the http:// or https:// scheme. This has been dropped in HTML5 specification. So if you use HTML5 and target HTML5 compatible browsers only, then you should be all fine by using a relative URI in the <base> tag.


As to using named/hash fragment anchors like <a href="#anchor">, query string anchors like <a href="?foo=bar"> and path fragment anchors like <a href=";foo=bar">, with the <base> tag you're basically declaring all relative links relative to it, including those kind of anchors. None of the relative links are relative to the current request URI anymore (as would happen without the <base> tag). This may in first place be confusing for starters. To construct those anchors the right way, you basically need to include the URI,

<a href="${uri}#anchor">hash fragment</a>
<a href="${uri}?foo=bar">query string</a>
<a href="${uri};foo=bar">path fragment</a>

其中${uri}基本上翻译成PHP中的$_SERVER['REQUEST_URI'], ${pageContext.request。JSP中的requestURI}和#{请求。JSF中的requestURI}。应该注意的是,像JSF这样的MVC框架有标签,减少了所有这些样板文件,并消除了<base>的需要。请参见a.o.使用什么URL链接/导航到其他JSF页面。

哈希值“#”目前与基本元素一起用于跳转链接,但仅限于谷歌Chrome和Firefox的最新版本,而不是IE9。

IE9似乎会导致页面被重新加载,而不会跳转到任何地方。如果你在一个iframe的外部使用跳转链接,同时引导该框架在该框架内的另一个页面上加载跳转链接,你将得到加载在该框架内的跳转链接页面的第二个副本。

我的建议是不要在管理url路径时使用<base>元素。为什么?

这只是把一个问题换为另一个问题。如果没有基本元素,您可以为相对路径和链接使用任何您喜欢的路径系统,而不必担心它们会中断。当你将基本元素设置为一个路径时,你就被“锁定”到设计所有url的工作路径,现在必须从基本路径更改所有路径。坏主意!

这意味着您现在必须编写更长的路径,并跟踪每条路径相对于这个基底的位置。更糟糕的是……当使用<base>元素时,他们建议您使用完全限定的基本路径来支持旧的浏览器(“https://www.example.com/”),所以现在您已经将域硬编码到页面中,或者使所有链接依赖于有效的域路径。

另一方面,当你再次从你的网站中删除基本路径时,你现在可以再次自由地使用更短的相对路径,这可以是完全限定的,从根目录使用绝对路径,或者使用真正相对于你所在的文件和文件夹的路径。它更灵活。最好的是,像“#hello”这样的片段可以正常工作,不需要任何额外的修复。再说一次,人们在制造不存在的问题。

另外,上面提到的使用基本url来帮助您将网页文件夹迁移到新的子文件夹位置的论点在今天并不重要,因为大多数现代服务器允许您快速将任何子文件夹设置为任何域下的新应用程序根文件夹。web应用程序的定义或“根”现在不受文件夹或域的限制。

这场争论看起来有点傻。因此,我建议去掉base url,并支持不使用它的旧的本地服务器-客户机默认路径系统。

注意:如果你的问题是控制路径由于一些新的API系统,解决方案很简单…在API中所有url和链接的路径上保持一致。不要依赖于浏览器对base或HTML5的支持,也不要像javascript API小孩子那样依赖于更新的马戏团把戏。简单地路径所有的锚标签一致,你将永远不会有问题。更重要的是,不管使用什么路径系统,您的web应用程序都可以立即移植到新的服务器上。

旧的又变新了!基本元素显然是试图为20年前的Web世界中从未存在过的问题创建解决方案,更不用说今天了。