我以前从未见过<base>
HTML tag实际使用过的地方。它的使用存在缺陷,这意味着我应该避免它吗?
我从未注意到它在现代制作网站(或任何网站)上的使用这一事实让我对它持怀疑态度,尽管它似乎可能有用于简化我网站链接的有用应用程序。
在使用基本标签几周之后,我最终找到了一些使用基本标签的主要陷阱,这使得它比首次出现时更不可取。从本质上讲,基本标记下的href='#topic'
和href=''
的更改非常与其默认行为不兼容,这种默认行为的更改可能很容易使第三方库在你的控件非常不可靠以意想不到的方式,因为它们在逻辑上取决于默认行为。通常,这些更改是微妙的,并且在处理大型代码库时会导致不那么明显的问题。我已经创建了一个回答,详细说明了我在下面遇到的问题。因此,在您进行广泛部署<base>
之前,请自行测试链接结果,这是我的新建议!
答案 0 :(得分:249)
在决定是否使用<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>
值以斜杠结尾,否则将相对于最后一个路径进行解释。
至于浏览器兼容性,这只会导致IE出现问题。 <base>
标记在HTML中指定为 not ,其结尾标记为</base>
,因此仅使用<base>
而没有结束标记是合法的。但是IE6认为不然,<{em> <base>
标记之后的整个内容在这种情况下被放置为HTML DOM树中<base>
元素的子 。这可能会导致Javascript / jQuery / CSS中出现无法解释的问题,即在{DOM(1)}等特定选择器中完全无法访问的元素,直到您在HTML DOM检查器中发现应该有html>body
(和base
)之间。
常见的IE6修复使用IE条件注释来包含结束标记:
head
如果您不关心W3验证器,或者您已经使用HTML5,那么您可以自行关闭它,每个webbrowser都支持它:
<base href="http://example.com/en/"><!--[if lte IE 6]></base><![endif]-->
关闭<base href="http://example.com/en/" />
标记还会立即修复WinXP SP3上IE6的insanity,以便在<base>
中以无限循环请求<script>
资源。
当您在src
标记中使用相对URI时,会出现另一个潜在的IE问题,例如<base>
或<base href="//example.com/somefolder/">
。这将在IE6 / 7/8中失败。然而,这不是浏览器的错;在<base href="/somefolder/">
标签中使用相对URI就是它自己的错误。 HTML4 specification表示它应该是绝对URI,因此从<base>
或http://
方案开始。这已在HTML5 specification中删除。因此,如果您仅使用HTML5并且仅针对HTML5兼容浏览器,那么通过在https://
标记中使用相对URI,您就可以了。
至于使用像<base>
这样的命名/散列片段锚点,查询字符串锚点如<a href="#anchor">
和路径片段锚点如<a href="?foo=bar">
,<a href=";foo=bar">
标记你基本上是声明相对于它的所有相对链接,包括这些锚点。没有任何相对链接相对于当前请求URI(如果没有<base>
标记将会发生)。这可能首先让初学者感到困惑。要以正确的方式构造这些锚点,您基本上需要包含URI,
<base>
其中<a href="${uri}#anchor">hash fragment</a>
<a href="${uri}?foo=bar">query string</a>
<a href="${uri};foo=bar">path fragment</a>
基本上转换为PHP中的${uri}
,JSP中的$_SERVER['REQUEST_URI']
和JSF中的${pageContext.request.requestURI}
。值得注意的是,像JSF这样的MVC框架有标签,减少了所有这些样板并消除了对#{request.requestURI}
的需求。另见a.o. What URL to use to link / navigate to other JSF pages
答案 1 :(得分:154)
基本标签似乎有一些非直观的效果,我建议您在依赖<base>
之前了解结果并自行测试!自从我发现之后尝试使用基本标记来处理具有不同网址的本地网站并且只发现了有问题的效果后,令我沮丧的是,我觉得有必要创建这些潜力的摘要其他人的陷阱。
我将在下面的案例中使用以下代码<base href="http://www.example.com/other-subdirectory/">
作为我的示例,并假装代码所在的网页为http://localsite.com/original-subdirectory
除非明确指出,否则任何链接或命名锚点或空白href都不会指向原始子目录: 基本标记使所有链接的方式不同,包括相同页面锚链接到基本标记的URL,例如:
<a href='#top-of-page' title='Some title'>A link to the top of the page via a named anchor</a>
的变强>
<a href='http://www.example.com/other-subdirectory/#top-of-page' title='Some title'>A link to an #named-anchor on the completely different base page</a>
<a href='?update=1' title='Some title'>A link to this page</a>
的变强>
<a href='http://www.example.com/other-subdirectory/?update=1' title='Some title'>A link to the base tag's page instead</a>
通过一些工作,您可以在您可以控制的链接上修复这些问题,方法是明确指定这些链接链接到它们所在的页面,但是当您将第三方库添加到依赖于标准行为,很容易造成大混乱。
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
由Izzy编辑:对于所有与我有同样困惑的人:
我刚刚自己测试过,结果如下:
#anchor
和?query
只会附加到指定的<BASE>
)。other.html
和dir/other.html
将从DOCUMENT_ROOT
开始,给定示例/other-subdirectory
正确(正确) )作为文件处理,因此被省略。因此,对于相对链接,BASE
适用于移动的页面 - 而锚点和?queries
需要明确指定文件名(BASE
具有尾部斜杠,或者最后一个元素与它所使用的文件的名称不对应。
将其视为<BASE>
将完整网址替换为文件本身(以及不它所在的目录),你会得到的东西对。假设此示例中使用的文件为other-subdirectory/test.html
(在移动到新位置之后),应该是正确的规范:
<强>
<base href="http://www.example.com/other-subdirectory/test.html
“&GT; 强>
- et voila,所有按预期工作:#anchor
,?query
,other.html
,very/other.html
,/completely/other.html
。< / p>
答案 2 :(得分:26)
好吧,等一下。我认为基本标签不值得这么糟糕的声誉。
基本标记的好处在于它使您能够以更少的麻烦进行复杂的URL重写。
这是一个例子。您决定将http://example.com/product/category/thisproduct移至http://example.com/product/thisproduct。您更改.htaccess文件以将第一个URL重写为第二个URL。
使用基本标记,您可以进行.htaccess重写,就是这样。没问题。但如果没有基本标记,您的所有相关链接都将中断。
URL重写通常是必要的,因为调整它们可以帮助您的网站的架构和搜索引擎可见性。没错,你需要解决人们提到的“#”和“问题”。但是基础标签在工具箱中占有一席之地。
答案 3 :(得分:19)
要决定是否应该使用它,您应该知道它的作用以及是否需要它。这已在this answer中部分概述,我也参与其中。但是为了更容易理解和遵循,这里有第二个解释。首先,我们需要了解:
<BASE>
,浏览器如何处理链接?对于某些示例,我们假设我们有以下网址:
A)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
。
让我们进一步假设,两个页面都包含一组链接:
1)完全合格的绝对链接(http://www...
)
2)本地绝对链接(/some/dir/page.html
)
3)相对链接,包括文件名(dir/page.html
)和
4)仅与“段”的相对链接(#anchor
,?foo=bar
)。
浏览器接收页面,然后呈现HTML。如果找到某个URL,则需要知道将其指向何处。对于链接1)来说,这一点总是很清楚,这是按原样进行的。所有其他人都依赖于呈现页面的URL:
URL | Link | 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>
应该替换浏览器中显示的网址 。因此,它呈现所有链接,就好像用户已调出<BASE>
中指定的URL一样。这解释了其他几个答案中的一些混淆:
<BASE>
中指定的那个与最初从用户调用的那个不同)<BASE>
的方式:
假设你想使用mod_rewrite
“美化”一些网址:
<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保留在浏览器中地址栏,而实际的加载)。现在该怎么办?
<BASE>
:打破所有相对链接(因为它们现在基于http://www.example.com/en/file
)<BASE HREF='http://www.example.com/some/dir>
:完全错了。 dir
将被视为指定网址的文件部分,因此,所有相关链接仍然会被破坏。<BASE HREF='http://www.example.com/some/dir/>
:已经更好了。但是“类型4”的相对链接仍然被打破(“案例B”除外)。<BASE HREF='http://www.example.com/some/dir/file.php>
:没错。一切都应该与这个一起工作。请注意,这适用于文档中的所有网址:
<A HREF=
<IMG SRC=
<SCRIPT SRC=
答案 4 :(得分:12)
Drupal最初依赖于<base>
标记,后来由于HTTP抓取工具的问题而决定不使用。高速缓存。
我一般不喜欢发布链接。但是这个真的值得分享,因为它可以使那些寻找<base>
标签的真实体验细节的人受益:
答案 5 :(得分:10)
使页面更容易离线观看;您可以将完全限定的URL放在基本标记中,然后正确加载远程资源。
答案 6 :(得分:5)
散列“#”目前适用于基本元素的跳转链接,但仅限于最新版本的Google Chrome和Firefox,而不是IE9。
IE9似乎会导致页面重新加载,而不会跳转到任何地方。如果您在iframe的外部使用跳转链接,同时指示框架在框架内的单独页面上加载跳转链接,您将获得在框架内加载的跳转链接页面的第二个副本。
答案 7 :(得分:5)
它可能不是很受欢迎,因为它并不为人所知。我不会害怕使用它,因为所有主流浏览器都支持它。
如果您的网站使用AJAX,您需要确保所有网页都正确设置,否则您最终可能无法解析链接。
只是不要在HTML 4.01严格页面中使用target
属性。
答案 8 :(得分:3)
另外,您应该记住,如果您在非标准端口上运行Web服务器,则还需要在base href中包含端口号:
<base href="//localhost:1234" /> // from base url
<base href="../" /> // for one step above
答案 9 :(得分:3)
如果在页面中内嵌SVG图像,则在使用base
标记时会出现另一个重要问题:
由于使用base
标记(如上所述),您实际上无法使用相对散列网址,例如
<a href="#foo">
因为它们将根据基本URL而不是当前文档的位置进行解析,因此不再相关。 因此,您必须将当前文档的路径添加到这些类型的链接中,例如
<a href="/path/to/this/page/name.html#foo">
因此,base
标记看似积极的一个方面(将长URL前缀从锚标记移开并获得更好,更短的锚点)完全适用于本地哈希URL。
在页面中内嵌SVG时,尤其令人讨厌,无论是静态SVG还是动态生成的SVG,因为在SVG there can be a lot of such references中,只要使用base
标记,它们就会全部中断,大多数情况下,但并非所有用户代理实现(在撰写本文时,Chrome至少仍然适用于这些场景)。
如果您正在使用模板系统或其他处理/生成页面的工具链,我总是会尝试删除base
标记,因为正如我所看到的那样,它会带来更多问题。桌子比它解决了。
答案 10 :(得分:2)
我从来没有真正看到过使用它的重点。提供很少的优势,甚至可能使事情变得更难使用。
除非您碰巧有数百或数千个链接,否则所有链接都在同一个子目录中。然后它可以节省几个字节的带宽。
作为事后的想法,我似乎记得IE6中的标签存在一些问题。您可以将它们放置在身体的任何位置,将站点的不同部分重定向到不同的位置。这在IE7中被修复,这破坏了很多网站。
答案 11 :(得分:2)
还有一个使用base-tag的站点,并且发生了所描述的问题。 (在升级jquery之后),能够通过这样的标签网址修复它:
<li><a href="{$smarty.server.REQUEST_URI}#tab_1"></li>
这使他们成为“本地”
我使用的参考文献:
http://bugs.jqueryui.com/ticket/7822 http://htmlhelp.com/reference/html40/head/base.html http://tjvantoll.com/2013/02/17/using-jquery-ui-tabs-with-the-base-tag/
答案 12 :(得分:2)
使用AngularJS,BASE标签默默地打破了$ cookieStore,我花了一段时间才弄清楚为什么我的应用程序不能再写cookie了。警告......
答案 13 :(得分:1)
要记住一件事:
如果您开发要在iOS上的UIWebView中显示的网页,则必须使用BASE标记。它根本不会起作用。是JavaScript,CSS,图像 - 除非指定了标记BASE,否则它们都不能用于UIWebView下的相对链接。
我之前已经被这个抓住了,直到我发现了。
答案 14 :(得分:1)
我找到了一种使用<base>
和基于锚点的链接的方法。您可以使用JavaScript来保持#contact
等链接的正常运行。我在一些视差页面中使用它,它对我有用。
<base href="http://www.mywebsite.com/templates/"><!--[if lte IE 6]></base><![endif]-->
...content...
<script>
var link='',pathname = window.location.href;
$('a').each(function(){
link = $(this).attr('href');
if(link[0]=="#"){
$(this).attr('href', pathname + link);
}
});
</script>
您应该在页面末尾使用
答案 15 :(得分:0)
我的建议是不要在管理网址路径中使用<base>
元素。为什么?
这只是将一个问题换成另一个。没有基本元素,您就可以将任何喜欢的路径系统用于相对路径和链接,而不必担心它们会断开。在将基本元素设置为“锁定”路径的那一刻,您将设计所有的url以使用该路径,现在必须更改所有路径才能从该基本路径工作。好主意!
这意味着您现在必须编写更长的路径,并跟踪每个路径相对于该基准的位置。更糟.....当使用<base>
元素时,他们建议您使用完全合格的基本路径来支持较旧的浏览器(“ https://www.example.com/”),因此现在您已将域硬编码到您的页面或使所有链接都依赖有效的域路径。
另一方面,从网站上再次删除基本路径的那一刻起,您现在就可以再次自由使用较短的相对路径,这些路径可以是完全限定的,可以使用来自根的绝对路径,也可以使用真正的路径相对于您所在的文件和文件夹。它更加灵活。并且所有片段中最好的片段如“ #hello”都可以正常工作,而无需任何其他修复。同样,人们正在制造不存在的问题。
此外,上面的论点是使用基本URL帮助您将网页文件夹迁移到新的子文件夹位置,今天实际上并不重要,因为大多数现代服务器都允许您将任何子文件夹快速设置为下面的新应用程序根文件夹。任何域。 Web应用程序的定义或“根”现在不受文件夹或域的约束。
整个辩论似乎有些愚蠢。因此,我说省略基本URL,并支持不使用它的较早的本机服务器-客户端默认路径系统。
注意:如果由于某些新的API系统而导致您的问题是控制路径,则解决方案很简单...在您的API中所有URL和链接的路径上保持一致。不要依赖浏览器对base或HTML5或更新的马戏团技巧的支持,例如javascript API kiddy。只需对所有锚定标记进行一致的路径设置,就不会有问题。而且,无论使用哪种路径系统,您的Web应用程序都可以立即移植到新服务器。
旧的又是新的!基本要素显然是关于尝试创建解决方案,以解决20年前在Web World中不存在的问题,而今天要少得多。
答案 16 :(得分:-1)
基本href示例
说一个包含链接的典型页面:
<a href=home>home</a> <a href=faq>faq</a> <a href=etc>etc</a>
。并链接到diff文件夹:
..<a href=../p2/home>Portal2home</a> <a href=../p2/faq>p2faq</a> <a href=../p2/etc>p2etc</a>..
使用base href,我们可以避免repeat基础文件夹:
<base href=../p2/>
<a href=home>Portal2-Home</a> <a href=faq>P2FAQ</a> <a href=contact>P2Contact</a>
所以“胜利... 尚未页面通常包含不同的网址和当前网络支持每页只有一个基本href ,所以胜利很快就会失去作为基础∙hrefed重复的基础,例如:
<a href=../p1/home>home</a> <a href=../p1/faq>faq</a> <a href=../p1/etc>etc</a>
<!--.. <../p1/> basepath is repeated -->
<base href=../p2>
<a href=home>Portal2-Home</a> <a href=faq>P2FAQ</a> <a href=contact>P2Contact</a>
<小时/> 的结论强>
(Base target可能有用。)基础href无用:
相关强>