使用<base>时,将锚链接引用当前页面

66

当我使用HTML <base> 标签为页面上所有相对链接定义基本URL时,锚点链接也会直接引用基本URL。有没有一种设置基本URL的方式,仍然允许锚点链接引用当前打开的页面?

例如,如果我在 http://example.com/foo/ 页面:


当前行为:

<base href="http://example.com/" />
<a href="bar/">bar</a> <!-- Links to "http://example.com/bar/" -->
<a href="#baz">baz</a> <!-- Links to "http://example.com/#baz" -->

期望的行为:

<base href="http://example.com/" />
<a href="bar/">bar</a> <!-- Links to "http://example.com/bar/" -->
<a href="#baz">baz</a> <!-- Links to "http://example.com/foo/#baz" -->

你正在使用服务器端编程语言吗?你可以在链接中动态内联当前请求的URI。另请参阅https://dev59.com/enI-5IYBdhLWcg3wYXL8#1889957 - BalusC
@BalusC 我不是,如果可能的话,我宁愿避免这种情况。 - Chris Down
好的,如果一切都已经是静态的了,那么就直接使用<a href="foo#baz"> - BalusC
1
我必须说这是错误的,您将基础设置为http://server/并告诉它导航到#baz,它将转到http://server/#baz。这就是相对URL的工作原理,以及使用<base>的效果,它会更改相对于哪个URL进行定位的基础部分。如果这不是您想要的结果,则您的链接不应该是相对的,或者它应该相对于基础的href(foo#baz)。 - Ruan Mendes
@JuanMendes 如果“foo”是一个未知的URL,那么这种方法就会失败。 - Abhi Beckert
@RuanMendes 我想大多数人都认为 href="#xyz" 总是指当前页面上的锚点,而不是完全不同的页面。毕竟 "#" 的整个意义就是跳转到文档的某个部分,而不是加载另一个页面。事实上,使用 <base href 可以使 "#" 自身(没有任何路径组件)在其他情况下不允许该行为的情况下加载完全不同的页面,我认为这不仅是技术上的缺陷,甚至是安全漏洞。 - Leslie Krause
13个回答

0

Joram van den Boezem的答案的基础上构建,但使用纯JavaScript:

document.addEventListener('DOMContentLoaded', function(){
    let pathname = location.href.split('#')[0];
    [].forEach.call(document.querySelectorAll("a[href^='#']"), function(a) {
        a.href = pathname + a.getAttribute("href");
    });
});

-1

从问题中给出的示例来看,为了实现所需的行为,我并不认为需要使用“base”标签。

页面位于http://example.com/foo/

以下代码将提供所需的行为:

<a href="/bar/">bar</a> <!-- Links to "http://example.com/bar/" -->
<a href="#baz">baz</a> <!-- Links to "http://example.com/foo/#baz" -->

诀窍是在字符串 href="/bar/" 的开头使用“/”。


1
有些人可能需要使用基础标签来构建一个视图库,以适应各种用例,比如在根目录和子目录中运行。移除基础标签并不是一个解决方案。 - turkinator

-2

如果您正在使用Angular 2或更高版本(并且只针对Web),您可以执行以下操作:

文件component.ts

document = document; // Make document available in template

文件 component.html

<a [href]="document.location.pathname + '#' + anchorName">Click Here</a>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接