对html <base>标签有什么建议?

Kzq*_*qai 454 html base-tag contextpath

我以前从未见过 实际使用过的<base>HTML标签.它的使用存在缺陷,这意味着我应该避免它吗?

事实上我从来没有注意到它在现代生产网站(或任何网站)上的使用让我对它持怀疑态度,尽管看起来它可能有用于简化我网站链接的有用应用程序.


编辑

使用基本标签几周后,我最终找到了使用基本标签的一些主要问题,这使得它比最初出现时更不可取.从本质上讲,变化href='#topic'href=''基本标签下是非常有它们的默认行为不兼容,并可以从默认行为,这种变化很容易使第三方库的控制范围之外的非常不可靠的 以意想不到的方式,因为它们在逻辑上依赖于默认行为.通常,这些更改是微妙的,并且在处理大型代码库时会导致不那么明显的问题.我已经创建了一个回答,详细说明了我在下面遇到的问题.因此,在您进行广泛部署之前,请自行测试链接结果<base>,这是我的新建议!

Bal*_*usC 256

在决定是否使用<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" />
Run Code Online (Sandbox Code Playgroud)

代替

<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" />
Run Code Online (Sandbox Code Playgroud)

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


至于浏览器兼容性,这只会导致IE中出现问题.该<base>标签是在HTML中指定为具有末端标签</base>,所以它是合法的,只是使用<base>没有结束标签.但是IE6认为否则,整个内容<base>标签是放置在这样的情况下孩子的的<base>在HTML DOM树元素.这可能会导致Javascript/jQuery/CSS中出现无法解释的问题,即在特定选择器中完全无法访问的元素html>body,直到您在HTML DOM检查器中发现它们之间应该存在base(和head).

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

<base href="http://example.com/en/"><!--[if lte IE 6]></base><![endif]-->
Run Code Online (Sandbox Code Playgroud)

如果您不关心W3验证器,或者您已经使用HTML5,那么您可以自行关闭它,每个webbrowser都支持它:

<base href="http://example.com/en/" />
Run Code Online (Sandbox Code Playgroud)

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

当您在<base>标记中使用相对URI时,将会出现另一个潜在的IE问题,例如<base href="//example.com/somefolder/"><base href="/somefolder/">.这将在IE6/7/8中失败.然而,这不是浏览器的错; 在<base>标签中使用相对URI 就是它自己的错误.所述HTML4说明书指出,它应为绝对URI,从而开始与所述http://https://方案.这已在HTML5规范中删除.因此,如果您仅使用HTML5并且仅针对HTML5兼容浏览器,那么通过在<base>标记中使用相对URI,您应该可以.


至于使用命名/散列片段锚点,像<a href="#anchor">查询字符串锚点<a href="?foo=bar">和路径片段锚点一样<a href=";foo=bar">,使用<base>标记你基本上声明相对于它的所有相对链接,包括那些锚点.相关链接都不再与当前请求URI相关(如果没有<base>标记就会发生).这可能首先让初学者感到困惑.要以正确的方式构造这些锚点,您基本上需要包含URI,

<a href="${uri}#anchor">hash fragment</a>
<a href="${uri}?foo=bar">query string</a>
<a href="${uri};foo=bar">path fragment</a>
Run Code Online (Sandbox Code Playgroud)

其中${uri}基本上转换为$_SERVER['REQUEST_URI']PHP,${pageContext.request.requestURI}JSP和#{request.requestURI}JSF.值得注意的是,像JSF这样的MVC框架有标签,减少了所有这些样板并消除了对它的需求<base>.另请参阅ao 用于链接/导航到其他JSF页面的URL.


Kzq*_*qai 160

基础标签效果的细分:

基本标签似乎有一些非直观的效果,我建议您在依赖之前了解结果并自行测试<base>!因为我尝试使用基本标签处理具有不同网址的本地网站之后发现了它们,并且发现了有问题的效果之后,令我沮丧的是,我觉得有必要为其他人创建这些潜在陷阱的摘要.

我将使用以下情况的基本标记:<base href="http://www.example.com/other-subdirectory/">作为我的示例,并假装代码所在的页面是http://localsite.com/original-subdirectory

重大的:

没有链接或命名锚点或空白hrefs将指向原始子目录,除非明确指出:基本标记使得所有链接都不同,包括相同页面锚链接到基本标记的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.htmldir/other.htmlDOCUMENT_ROOT给定示例开始,/other-subdirectory被(正确地)视为文件,因此被省略.

因此,对于相对链接,BASE可以在移动的页面上正常工作 - 而锚点则?queries需要显式指定文件名(BASE具有尾部斜杠,或者最后一个元素与其使用的文件名不对应).

可以把它想象为<BASE>完整的URL替换为文件本身(而不是它所在的目录),并且你会把事情弄清楚.假设此示例中使用的文件是other-subdirectory/test.html(在移动到新位置之后),正确的规范应该是:

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

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


Sum*_*mer 26

好吧,等一下.我不认为基本标签值得这个坏名声.

基本标签的好处在于它使您能够以更少的麻烦进行复杂的URL重写.

这是一个例子.您决定将http://example.com/product/category/thisproduct移至http://example.com/product/thisproduct.您更改.htaccess文件以将第一个URL重写为第二个URL.

使用基本标记,您可以进行.htaccess重写,就是这样.没问题.但如果没有基本标记,您的所有相关链接都将中断.

URL重写通常是必要的,因为调整它们可以帮助您的网站的架构和搜索引擎可见性.没错,你需要解决人们提到的"#"和"问题".但是基本标签在工具箱中占有一席之地.

  • 从我的角度来看,问题是面向未来的问题.如果在页面上使用基本标记,则与该页面交互的所有其他库都将受到基本标记的影响,包括可能依赖于裸锚标记或散列的默认行为的第三方库. (10认同)
  • @Kzqai,+1好点,但有很多网站不使用有缺陷的库.**问题不在于基础href,**它与库有关,需要在那里修复. (4认同)
  • @Pacerier,我说问题确实是基于href.或者更确切地说,问题是浏览器看起来不够聪明,根本不会影响以#开头的锚点href.我试图用javascript解决这个问题,这导致库使用`href ='#'`链接(例如bootstrap)的问题.责怪库就像把它们归咎于HTML出错的其他一切.对于现代工作来说,这是一个过时的工具,简单如此. (2认同)
  • "复杂的URL重写更轻松." - 虽然,在这种情况下,`base`标签可以说是_workaround_,因为它首先没有(正确)使用了根相对URL(甚至是绝对URL). (2认同)

Izz*_*zzy 20

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

如何在不<BASE>使用浏览器的情况下处理链接?

对于某些示例,我们假设我们有以下URL:

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
Run Code Online (Sandbox Code Playgroud)

现在使用的 <BASE>是什么变化?

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

  • 再次,"完全合格的绝对链接"("类型1")没有任何变化
  • 对于本地绝对链接,目标服务器可能会更改(如果指定的服务器<BASE>与最初从用户调用的服务器不同)
  • 相对URL在这里变得至关重要,因此您必须特别注意如何设置<BASE>:
    • 最好避免将其设置为目录.这样做,"类型3"的链接可能继续工作,但它肯定会打破"类型4"的那些("案例B"除外)
    • 在大多数情况下,将其设置为完全限定的文件名会产生所需的结果.

一个例子最好地解释了它

假设您想使用以下方式"美化"某些URL mod_rewrite:

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

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

  • 没有<BASE>指定:打破所有相对链接(因为它们将基于http://www.example.com/en/file现在)
  • <BASE HREF='http://www.example.com/some/dir>:完全错了.dir将被视为指定URL 的文件部分,因此仍然会破坏所有相对链接.
  • <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=
  • ...


Amr*_*afa 12

Drupal最初依赖于<base>标签,后来由于HTTP爬虫和缓存问题而决定不使用.

我一般不喜欢发布链接.但是这个真的值得分享,因为它可以让那些寻找<base>标签真实体验细节的人受益:

http://drupal.org/node/13148


Eri*_*rik 10

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


Ben*_*n S 5

它可能不是很受欢迎,因为它并不为人所知.我不会害怕使用它,因为所有主流浏览器都支持它.

如果您的网站使用AJAX,您需要确保所有网页都正确设置,否则您最终可能无法解析链接.

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


小智 5

散列"#"目前适用于跳转链接以及基本元素,但仅适用于最新版本的Google Chrome和Firefox,而不是IE9.

IE9似乎导致页面重新加载,而不会跳转到任何地方.如果您在iframe的外部使用跳转链接,同时指示框架在框架内的单独页面上加载跳转链接,您将获得在框架内加载的跳转链接页面的第二个副本.