参考资料

  1. HTML DOM 返回一个锚的名字 实例
  2. HTML DOM 被按下的键盘键的keycode?
  3. HTML DOM单元格内容水平对齐
  4. HTML DOM 返回图像映射某个区域的替代文字实例
  5. HTML DOM 获取第一个链接ID的实例
  6. HTML DOM 返回文档的最后一次修改时间 实例
  7. HTML DOM 对image排版
  8. HTML DOM 返回文档中的图像数
# HTML DOM 获取页面上所有相对链接的基链接

## 概述

在HTML中,相对链接是基于`<base>`标签或当前文档URL解析的。本文将详细介绍如何使用DOM获取页面上所有相对链接的基链接(base URL),并提供相关实例和扩展功能。

## `<base>` 标签介绍

`<base>`标签定义了页面中所有相对URL的基准URL。一个文档中只能有一个`<base>`元素,它必须位于`<head>`部分。

```html
<head>
    <base href="https://www.example.com/" target="_blank">
</head>
```

- `href`属性指定基准URL
- `target`属性指定默认打开方式(可选)

## 获取基链接的方法

### 1. 获取文档的基链接

```javascript
// 获取文档中定义的<base>标签的href属性
const baseHref = document.querySelector('base')?.href || window.location.href;

// 或者使用DOM API
const baseElement = document.getElementsByTagName('base')[0];
const baseUrl = baseElement ? baseElement.href : document.URL;
```

### 2. 获取所有相对链接并转换为绝对链接

```javascript
function getAllRelativeLinks() {
    const baseUrl = document.querySelector('base')?.href || window.location.href;
    const base = new URL(baseUrl);
    const links = document.querySelectorAll('a[href^="./"], a[href^="../"], a[href^="/"]');
    
    return Array.from(links).map(link => {
        try {
            return new URL(link.href, base).href;
        } catch {
            return null;
        }
    }).filter(Boolean);
}

const absoluteLinks = getAllRelativeLinks();
console.log(absoluteLinks);
```

## 完整实例

```html
<!DOCTYPE html>
<html>
<head>
    <title>相对链接处理示例</title>
    <base href="https://www.example.com/base/">
</head>
<body>
    <h1>相对链接示例</h1>
    
    <a href="page1.html">相对链接1</a>
    <a href="/page2.html">根相对链接</a>
    <a href="../page3.html">上级目录链接</a>
    <a href="https://www.othersite.com/page4.html">绝对链接</a>
    
    <script>
        document.addEventListener('DOMContentLoaded', function() {
            // 获取基准URL
            const baseElement = document.querySelector('base');
            const baseUrl = baseElement ? baseElement.href : window.location.href;
            console.log('基准URL:', baseUrl);
            
            // 获取所有相对链接并转换为绝对URL
            const links = document.querySelectorAll('a');
            links.forEach(link => {
                if (!link.href.startsWith('http')) {
                    const absoluteUrl = new URL(link.href, baseUrl).href;
                    console.log(`相对链接: ${link.href} → 绝对URL: ${absoluteUrl}`);
                }
            });
        });
    </script>
</body>
</html>
```

## CSS扩展:为相对链接添加样式

可以使用CSS属性选择器为相对链接添加特殊样式,方便用户识别:

```css
/* 为所有相对链接添加样式 */
a[href^="./"], 
a[href^="../"], 
a[href^="/"] {
    border-left: 3px solid #ff9800;
    padding-left: 5px;
    background-color: #fff8e1;
}

/* 为没有明确target属性的相对链接添加样式 */
a[href^="./"]:not([target]), 
a[href^="../"]:not([target]), 
a[href^="/"]:not([target]) {
    background-color: #ffecb3;
}

/* 鼠标悬停效果 */
a[href^="./"]:hover, 
a[href^="../"]:hover, 
a[href^="/"]:hover {
    text-decoration: underline wavy;
}
```

## 实用功能扩展

### 1. 验证所有链接是否有效

```javascript
async function checkLinks() {
    const links = document.querySelectorAll('a');
    const baseUrl = document.querySelector('base')?.href || window.location.href;
    
    for (const link of links) {
        const url = new URL(link.href, baseUrl).href;
        
        try {
            const response = await fetch(url, { method: 'HEAD' });
            if (!response.ok) {
                link.style.border = '2px solid red';
                console.warn(`无效链接: ${url}`);
            }
        } catch (error) {
            link.style.border = '2px solid red';
            console.error(`无法访问的链接: ${url}`, error);
        }
    }
}

// 注意: 由于CORS限制,此功能可能无法检查跨域链接
```

### 2. 批量修改相对链接

```javascript
function updateRelativeLinks(newBaseUrl) {
    const links = document.querySelectorAll('a[href^="./"], a[href^="../"], a[href^="/"]');
    
    links.forEach(link => {
        const absoluteUrl = new URL(link.href, newBaseUrl).href;
        link.href = absoluteUrl;
    });
    
    // 更新或添加base标签
    let baseElement = document.querySelector('base');
    if (!baseElement) {
        baseElement = document.createElement('base');
        document.head.appendChild(baseElement);
    }
    baseElement.href = newBaseUrl;
}
```

## 注意事项

1. 如果页面没有`<base>`标签,浏览器会使用当前文档的URL作为基准
2. 使用`new URL()`构造函数可以正确处理相对路径的解析
3. 跨域链接检查可能受到浏览器安全策略的限制
4. 修改`<base>`标签会影响页面上的所有相对URL,包括图片、脚本等

通过以上方法,您可以有效地处理页面中的相对链接,并根据需要进行转换、验证或样式化。