Chrome/Firefox中内联Javascript事件处理程序中的"用户名"和"密码"

Ell*_*lle 10 html javascript firefox google-chrome

变量usernamepassword不保留其原始值(如脚本标签定义)或不能从onclick事件访问,但是做一个函数调用输出变量一样.似乎变量在该范围内被重新定义,因为即使我没有定义变量,它们也不是未定义的.

它似乎是由于变量被命名,username并且password如下面的代码示例所示(usr并按passwd预期工作).

有理由相信这种行为已被引入最新版本的浏览器,因为较旧的Firefox没有展示它.

这是一个可重现的代码示例(在Google Chrome 32/Firefox 26中测试 - 但是有些用户报告说它不适合他们):

<html>
<head>
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
    <script>
        var username = "Administrator";
        var password = "AdminPass";

        var usr = "Jordan";
        var passwd = "JordanPass";

        function printCredentials() {
            $("#out").append("username is: " + username + "<br/>");
            $("#out").append("password is: " + password + "<br/>");
            $("#out").append("usr is: " + usr + "<br/>");
            $("#out").append("passwd is: " + passwd + "<br/>");
        }
    </script>
</head>
<body>
    <a href="#" onclick="printCredentials()">This works</a><br/>
    <a href="#" onclick="$('#out').append('username is: ' + username + '<br/>'); $('#out').append('password is: ' + password + '<br/>'); $('#out').append('usr is: ' + usr + '<br/>');  $('#out').append('passwd is: ' + passwd + '<br/>');">But this doesn't (properly)</a><br/>
    <div id="out" style="background: yellow"></div>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

JSFiddle演示

使用jQuery是可选的,常规JS也是如此.

点击第二个链接打印出来usr,并passwd如预期,但usernamepassword空白.奇怪的是,它在Internet Explorer中按预期工作(打印所有字段).

这里发生了什么?

Rez*_*ned 5

这是一个细分为什么你看不到usernamepassword属性

首先,<a>tag能够解析urlin href属性并将解析后的值转换为自己的属性.

注意 URL语法<protocol>://<user>:<password>@<host>:<port>/<url-path>

var a = document.createElement('a');
a.setAttribute('href', 'http://john:doe@google.com');

// Do you get the idea now?
a.username // prints "john"
a.password // prints "doe"
Run Code Online (Sandbox Code Playgroud)

就是这样,你的内联onclick是针对a已经同时具有属性usernamepassword属性定义的范围执行的(带有""值)

+----------------+
| window.username|  <-- your "Administrator"
|                |
| +------------+ |
| | a.username | |  <-- empty by default ""
| +------------+ |
+----------------+
Run Code Online (Sandbox Code Playgroud)

编辑:如果你想看到Chrome的源代码,它定义了用户名/密码界面和实现

界面:https://code.google.com/p/chromium/codesearch#chromium/src/third_party/WebKit/Source/core/dom/DOMURLUtils.h&l=47&rcl=1391416355

实施:https://code.google.com/p/chromium/codesearch#chromium/src/third_party/WebKit/Source/core/dom/DOMURLUtils.cpp&l=48&rcl=1391416355

说明:当我回答这个问题时,我假设每个人都已经知道关于事件和javascript中的this关键字,但看起来不够清楚(我的不好).onclickScope

这条线"is being executed against <a>'s scope"意味着,

onclick="alert(username)" === onclick="alert(this.username)"
Run Code Online (Sandbox Code Playgroud)

也就是说,你可以想到任何东西onclick都是一个匿名函数,它必须<a>标记为

onclick = function() {
    log(this);     // 1. bound to `<a>` not `window`
    log(username); // 2. implies `this.username` unless you explicitly declare 'var username`
}
Run Code Online (Sandbox Code Playgroud)

Javascript范围的工作原理是,如果它username在本地范围内找不到该变量(),它将查看它的外部范围window.username.

希望能让它更清晰.


Qan*_*avy 3

这实际上被定义为HTML5 标准的一部分。该<a>元素被指定为具有以下 DOM 接口:

interface HTMLAnchorElement : HTMLElement {
           attribute DOMString target;
           attribute DOMString download;

           attribute DOMString rel;
  readonly attribute DOMTokenList relList;
           attribute DOMString hreflang;
           attribute DOMString type;

           attribute DOMString text;
};
HTMLAnchorElement implements URLUtils;
Run Code Online (Sandbox Code Playgroud)

URLUtils实际上取自 URL 标准,其中定义了其行为。这就是这些属性的实际来源:

[NoInterfaceObject]
interface URLUtils {
  stringifier attribute [EnsureUTF16] DOMString href;
  readonly attribute DOMString origin;

           attribute [EnsureUTF16] DOMString protocol;
           attribute [EnsureUTF16] DOMString username;
           attribute [EnsureUTF16] DOMString password;
           attribute [EnsureUTF16] DOMString host;
           attribute [EnsureUTF16] DOMString hostname;
           attribute [EnsureUTF16] DOMString port;
           attribute [EnsureUTF16] DOMString pathname;
           attribute [EnsureUTF16] DOMString search;
           attribute URLSearchParams? searchParams;
           attribute [EnsureUTF16] DOMString hash;
};
Run Code Online (Sandbox Code Playgroud)

这些 DOM 属性被定义为 getter 和 setter,它们解析并返回相关值(在获取时),并href在设置有效值时更改该值。例如,protocol简单地定义为:

协议属性必须运行以下步骤:

  1. 如果 url 为 null,则返回“ :”。
  2. 返回方案和“ :”连接。

这些部分(例如“方案”)取自href值,该值被解析为有效的 URL。

请注意,描述接口的方式称为Web IDL,它可以被视为一种伪代码形式,尽管它实际上是在其自己的规范下明确指定的。

因为它是一个新标准,所以最近才实现(这可能解释了为什么这个问题之前不相关)——仅由 Firefox 在版本 26 中实现。