要获取未被标准化的原始 URL(即未经过浏览器自动处理的原始字符串),需要绕过 getAttribute
的标准化行为。以下是几种方法:
1. 直接访问元素的 attributes
属性
HTML 元素的 attributes
属性返回一个 NamedNodeMap,其中包含元素的所有属性节点。通过它可以直接获取原始的、未经标准化的属性值。
示例代码
const element = document.querySelector('a');
const rawHref = element.attributes.getNamedItem('href').value;
console.log(rawHref); // 输出原始URL(如 "./path#fragment")
特点
- 不会标准化 URL:即使属性值是相对路径或包含特殊字符(如
#
,?
),也会原样返回。 - 兼容性:支持所有现代浏览器。
2. 使用 outerHTML
+ 正则解析
如果无法直接访问元素对象(例如动态生成的 HTML 字符串),可以通过解析 outerHTML
提取原始属性值。
示例代码
const html = '<a href="./test#section">Link</a>';
const parser = new DOMParser();
const doc = parser.parseFromString(html, 'text/html');
const element = doc.querySelector('a');
// 方法1:通过attributes获取
const rawHref = element.attributes.href.value;
// 方法2:通过正则匹配outerHTML
const hrefMatch = element.outerHTML.match(/href=["'](.*?)["']/i);
if (hrefMatch) {
console.log(hrefMatch[1]); // 输出 "./test#section"
}
3. Hook setAttribute
保存原始值
如果需要长期监控动态修改的 URL,可以劫持 setAttribute
方法,在设置属性时保存原始值。
示例代码
(function() {
const originalSetAttr = Element.prototype.setAttribute;
Element.prototype.setAttribute = function(name, value) {
if (name === 'href' || name === 'src') {
this._rawUrl = value; // 存储原始值
}
originalSetAttr.call(this, name, value);
};
// 获取原始值的扩展方法
Element.prototype.getRawAttribute = function(name) {
return this._rawUrl || this.getAttribute(name);
};
})();
// 测试
const link = document.createElement('a');
link.setAttribute('href', './path?query=1#hash');
console.log(link.getRawAttribute('href')); // "./path?query=1#hash"
console.log(link.getAttribute('href')); // "https://domain.com/path?query=1"
关键区别对比
方法 | 是否标准化 | 适用场景 |
---|---|---|
getAttribute('href') |
✅ 是 | 需要解析完整URL时 |
element.attributes.href.value |
❌ 否 | 获取原始设置的字符串 |
Hook setAttribute |
❌ 否 | 动态监控修改 |
注意事项
- 相对路径处理
element.href
会返回完整的绝对路径(标准化)。
attributes.href.value
保留原始的相对路径(如../file.html
)。
- 编码差异
getAttribute()
可能对特殊字符解码,而attributes.value
保留原编码(如空格可能是%20
)。
- 性能开销
- Hook API(如劫持
setAttribute
))可能影响性能,建议仅在调试时使用。
- Hook API(如劫持
如果需要精准捕获用户输入的原始数据(例如安全审计或爬虫开发),优先使用 Method #1 (attributes
)!
内容由零声教学AI助手提供,问题来源于学员提问