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

时间:2014-01-30 03:49:27

标签: javascript html google-chrome firefox

变量usernamepassword不保留其原始值(如脚本标记中所定义)或无法从onclick事件访问,但是进行输出变量的函数调用。似乎变量在该范围内被重新定义,因为即使我没有定义变量,它们也不会被定义。

这似乎是由于变量名为usernamepassword,如下面的代码示例所示(usrpasswd按预期工作。)< / p>

有理由相信这种行为已被引入最新版本的浏览器,因为较旧的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>

JSFiddle demo

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

点击第二个链接会按预期打印出usrpasswd,但usernamepassword为空。奇怪的是,它在Internet Explorer中按预期工作(打印所有字段)。

这里发生了什么?

4 个答案:

答案 0 :(得分:5)

以下是您无法看到usernamepassword属性的原因

首先,<a>标记能够解析url属性中的href并将解析后的值转换为自己的属性。

注意网址语法<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"

就是这样,您的内联onclick正在针对a的范围执行,该范围已经定义了usernamepassword属性(带有“”值)

+----------------+
| window.username|  <-- your "Administrator"
|                |
| +------------+ |
| | a.username | |  <-- empty by default ""
| +------------+ |
+----------------+

编辑:如果您想查看Chrome的源代码,请在其中定义用户名/密码界面&amp;实施

界面: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

说明:当我回答这个问题时,我认为每个人都已经知道this事件中的onclick关键字和javascript中的Scope,但看起来像是不够清楚(我的坏)。

此行"is being executed against <a>'s scope"表示

onclick="alert(username)" === onclick="alert(this.username)"

也就是说,你可以想到onclick中的任何内容都是一个绑定到<a>标签的匿名函数,所以

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

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

希望能让它更清晰。

答案 1 :(得分:3)

这实际上是the HTML5 standard的一部分。指定<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;

URLUtils实际上是taken from the URL standard,其行为已定义。这是这些属性实际来自的地方:

[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;
};

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

  

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

     
      
  1. 如果网址为空,请返回“:”。
  2.   
  3. 返回方案并且“:”连接在一起。
  4.   

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

请注意,描述接口的方式称为Web IDL,可以将其视为一种伪代码形式,尽管它实际上已经明确指定under its own specification

因为它是一个新标准,它最近才实现(这可能解释了为什么这个问题之前没有相关性) - 这只是由Firefox在版本26中实现的。

答案 2 :(得分:1)

虽然我不确定其背后的确切原因,但问题在于您的变量名称'username'和'password'。

如果您更改了变量名称,则一切正常。

  

除了上述保留字之外,您最好避免使用以下标识符作为JavaScript变量的名称。这些是依赖于实现的JavaScript对象,方法或属性的预定义名称(可以说,有些应该是保留字):... password ...   http://www.javascripter.net/faq/reserved.htm

答案 3 :(得分:0)

这是我的小提琴,它起作用:http://jsfiddle.net/kP2EU/2/

我没有允许使用var username和var password,而是将用户名和密码分配为窗口对象window.usernamewindow.password的属性,然后在锚标记的onClick事件中使用这些引用。这两种情况都很好。

<强> JS

 window.username = "Administrator";
 window.password = "AdminPass";

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

 function printCredentials() {
     $("#out").append("username is: " + window.username + "<br/>");
     $("#out").append("password is: " + window.password + "<br/>");
     $("#out").append("usr is: " + usr + "<br/>");
     $("#out").append("passwd is: " + passwd + "<br/>");
 }

<强> HTML

<a href="#" onclick="printCredentials()">This works</a>
<br/> <a href="#" onclick="$('#out').append('username is: ' + window.username + '<br/>'); $('#out').append('password is: ' + window.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>

我仍然找不到任何对chrome环境中任何内容的引用,这些引用说明你不能在锚标记的onClick事件中使用变量名用户名和密码。

更新http://jsfiddle.net/kP2EU/3/ 而不是分配给window.usernamewindow.password,它仍使用var usernamevar password,但锚标记引用window.usernamewindow.password

更新2 : 我正在使用chrome中的开发人员工具并且能够返回到onClick事件堆栈,并且发现用户名和密码是我猜测chrome定义的锚标记的属性。我正在努力弄清楚它的定义在哪里提供链接或更多信息。