我从未见过<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!


当前回答

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

其他回答

它可能不是很流行,因为它不是很出名。我不会害怕使用它,因为所有主流浏览器都支持它。

如果您的站点使用AJAX,您将希望确保所有页面都正确设置了AJAX,否则可能会出现无法解析的链接。

只是不要在HTML 4.01 Strict页面中使用target属性。

好吧,等一下。我认为基本标签配不上这种坏名声。

base标记的优点是它使您能够以更少的麻烦进行复杂的URL重写。

举个例子。您决定将http://example.com/product/category/thisproduct移动到http://example.com/product/thisproduct。修改.htaccess文件,将第一个URL重写为第二个URL。

有了base标签,就可以重写.htaccess了。没有问题。但是如果没有base标签,所有的相对链接都将中断。

URL重写通常是必要的,因为调整它们可以帮助您的网站的架构和搜索引擎可见性。的确,对于人们提到的“#”和“”问题,您需要变通方法。但是基本标记应该在工具包中占有一席之地。

要决定是否应该使用它,您应该了解它的功能以及是否需要它。这一点在我的回答中已经有了部分概述,我也对此做出了贡献。但是为了更容易理解和理解,这里有第二个解释。首先我们需要了解:

浏览器如何处理没有<BASE>被使用的链接?

对于一些例子,让我们假设我们有这些url:

一)http://www.example.com/index.html B) http://www.example.com/ C) http://www.example.com/page.html D) http://www.example.com/subdir/page.html

A和B都会将相同的文件(index.html)发送到浏览器,C当然发送page.html, D发送/subdir/page.html。

让我们进一步假设,两个页面都包含以下类型的链接:

完全限定的绝对链接(http://www…) 本地绝对链接(/some/dir/page.html) 相对链接,包括文件名(dir/page.html)和 只有“分段”的相对链接(#anchor, ?foo=bar)。

浏览器接收页面,并呈现HTML。如果它找到某个URL,它需要知道指向哪里。对于Link 1)来说,这一点总是很清楚的,因为它是按原样进行的。所有其他依赖于呈现页面的URL:

URL     | Type | Result
--------+------+--------------------------
A,B,C,D |    2 | http://www.example.com/some/dir/page.html
A,B,C   |    3 | http://www.example.com/dir/page.html
D       |    3 | http://www.example.com/subdir/dir/page.html
A       |    4 | http://www.example.com/index.html#anchor
B       |    4 | http://www.example.com/#anchor
C       |    4 | http://www.example.com/page.html#anchor
D       |    4 | http://www.example.com/subdir/page.html#anchor

现在使用<BASE>会有什么变化?

<BASE>应该替换浏览器显示的URL。因此,它呈现所有链接,就好像用户调用了<BASE>中指定的URL一样。这解释了其他几个答案中的一些困惑:

again, nothing changes for "fully qualified absolute links" ("type 1") for "local absolute links", the targeted server might change (if the one specified in <BASE> differs from the one being called initially from the user) "relative URLs" become critical here, so you've got to take special care how you set <BASE>: better avoid setting it to a directory. Doing so, links of "type 3" (relative dir + filename) might continue to work, but it most certainly breaks those of "type 4" (relative + segment); except for "case B" (no path or filename). setting it to the fully qualified file name produces, in most cases, the desired results.

举个例子最好地说明了这一点

假设你想用mod_rewrite“美化”一些URL:

<DOCUMENT_ROOT>/some/dir/file.php?lang = en 真实网址:http://www.example.com/some/dir/file.php?lang=en 友好的网址:http://www.example.com/en/file

让我们假设mod_rewrite用于透明地将用户友好的URL重写为真实的URL(没有外部重定向,因此“用户友好”的URL保留在浏览器的地址栏中,而真实的URL被加载)。现在该怎么办?

no <BASE> specified: breaks all relative links (as they would be based on http://www.example.com/en/file now) <BASE HREF='http://www.example.com/some/dir>: Absolutely wrong. dir would be considered the file part of the specified URL, so still, all relative links are broken. <BASE HREF='http://www.example.com/some/dir/>: Better already. But relative links of "type 4" are still broken (except for "case B"). <BASE HREF='http://www.example.com/some/dir/file.php>: Exactly. Everything should be working with this one.

最后一点

请记住,这适用于文档中的所有url:

< A HREF = < IMG SRC = < SCRIPT SRC = ...

在决定是否使用<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页面。

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

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