为什么 script.src 会像它一样工作

Why does script.src work as it does?

本文关键字:一样 工作 script src 为什么      更新时间:2023-09-26

我找不到任何关于script标签属性的文档或规范src

浏览器操作此属性的值,该值始终反映绝对 URI。让我们考虑以下示例:

域: https://example.com

脚本标签: <script src="/path/a/b/c.js"></script>

script.getAttribute("src")>/path/a/b/c.js
脚本.src> https://example.com/path/a/b/c.js

如您所见,srcgetAttribute("src")之间存在差异。

我想知道在哪里可以找到有关它的详细信息(浏览器实现的文档/规范/源代码)。

此功能在浏览器(包括移动设备)中的支持是什么?

我在HTML5规范中找到了它:

首先,这是讨论<script>标签的.src属性:

IDL 属性 src、类型、字符集、延迟,每个属性都必须反映 同名的相应内容属性。

然后,如果您按照该规范中的链接查看"reflect"的含义,则可以得到以下内容:

如果反映 IDL 属性是其内容的 DOMString 属性 属性被定义为包含 URL,然后在获取时,IDL 属性必须解析内容属性相对于 元素并返回生成的绝对 URL(如果 成功,否则为空字符串;并在设置时,必须设置 指定文本值的内容属性。如果内容 属性不存在,IDL 属性必须返回默认值, 如果内容属性有一个,或者空字符串。

因此,用简短的形式来描述一下:如果您设置了 .src 属性(或采用 URL 的任何其他属性),则您设置的内容将存储为属性。 获取 .src 属性时,返回的值是相对于基 URL 解析属性后生成的绝对 URL。

至于.getAttribute(),规范在这里。 它只是说:

按名称检索属性值。

返回值

多姆斯特林 |字符串形式的 Attr 值,或空字符串(如果该属性) 没有指定的或默认值。

值得注意的是,此描述中缺少与 URL 属性在直接读取其属性时具有的特殊行为相关的任何内容,如上所述。 因此,使用.getAttribute()没有这种特殊的"反映"行为。 它只返回属性的原始值,没有特殊的getter行为。


这是一种预期的行为,并且已经存在了很长时间。 还有针对特定浏览器的特定开发人员网站来描述该行为。

读取 .src 属性始终返回完全限定的 URL,无论您在 HTML 中或通过 Javascript 分配了什么。

使用 .getAttribute("src") 读取同一属性将准确返回 HTML 中的内容。

Microsoft记录了 IE 在这方面的行为方式,对于此处以 IE8 开头的属性,URI 为任何标记。

Mozilla在这里记录了Firefox在这方面对图像的行为。

图像演示(尽管具有 srchref 属性的所有类型的标记似乎都具有相同的行为(包括<script>标记):

var t = document.getElementById("target");
log("target.getAttribute('src') = ", target.getAttribute('src'));
log("target.src = ", target.src);
<head>
  <script src="http://files.the-friend-family.com/log.js"></script>
  <base href="http://dummyimage.com">
</head>
<img id="target" src="/200x100/000/fff">

事实上,这里有一个小实用程序可以利用这一事实:

function makeAbsolute(uri) {
    var a = document.createElement("a");
    a.href = uri;
    return a.href;
}
var x = makeAbsolute("test.html");
document.write(x);

具体来说<script src="...">,MDN 文档没有提到 src 属性必须返回完全限定的 URI。

规范仅处理src属性:

src 属性(如果指定)提供要使用的外部脚本资源的地址。属性的值必须是有效的非空 URL,可能被空格包围,用于标识 type 属性给出的类型(如果存在)或类型为"text/javascript"(如果属性不存在)的脚本资源。资源是给定类型的脚本资源,如果该类型标识脚本语言,并且资源符合该语言规范的要求。

尽管如此,我已经检查了Chrome,Firefox和Safari都实现了您提到的行为。


通常,元素属性和属性之间存在差异,两者不一定必须一致。

属性

在不深入规范的情况下,Element实例维护一个attributes集合,该集合保存节点上的 DOM 属性。例如,以下元素

<div id="test"></div>

具有值为 "test"id 属性。请注意,属性名称和值始终是字符串(更准确地说,DOMString s)。

可以使用 element.getAttribute(name) 访问属性。

性能

此外,Element实例与任何 JavaScript 对象一样,具有一组可直接在实例上访问的属性。例如,innerHTML是一个属性。

属性可以简单地使用点符号访问,即 element.innerHTML .他们被允许有吸气手和二传手。


对于 <script> 元素(HTMLScriptElement 的实例),既有 src 属性,也有 src 属性。观察:

// check out the descriptor of the src property
console.log(Object.getOwnPropertyDescriptor(HTMLScriptElement.prototype, 'src').get);
var script = document.createElement('script');
console.log(script.getAttribute('src'));
console.log(script.src);
script.src = 'test.js';
console.log(script.getAttribute('src'));
console.log(script.src);
script.setAttribute('src', 'foo.js');
console.log(script.getAttribute('src'));
console.log(script.src);

输出(铬 47):

function () { [native code] }
null
test.js
http://stacksnippets.net/test.js
foo.js
http://stacksnippets.net/foo.js

访问元素上的 src 属性将调用该属性的 getter,该属性返回完全限定的 URL。检索 src 属性将按原样返回您在此处设置的任何字符串,如果尚未设置该属性,则返回null