在IE中,如何使用javascript控制显示浏览器的已保存用户名/密码列表和“保存用户名/密码”对话框?

在我的Web应用程序中,有两个页面处理用户帐户,即用户帐户创建/编辑页面和登录页面。除了我想要的以外,这些页面的效果与预期的差不多:

  • 防止浏览器的用户名/密码列表(又名列表)显示在用户帐户创建/编辑页面上,

  • 有条件地在登录页面上显示列表,

  • 提交用户帐户创建/编辑页面后,有条件地显示浏览器的“保存用户名/密码”对话框(又名“保存”对话框),并且

  • 防止在提交登录页面后显示保存对话框。

用户帐户创建/编辑页面上有一个“我的设备”复选框,可以选中/取消选中该复选框以控制我的网络应用中的某些功能,并允许浏览器在此页面上显示/隐藏其保存对话框和列表并在登录页面上。

虽然在帐户创建/修改页面上,该列表永远都不会显示,所以黑客无法轻易看到已经保存到浏览器的用户名/密码管理器中的用户名。但是,用户登录后,可以在此页面上更改自己的用户名和/或密码,然后提交更改,并且如果选中了“我的设备”复选框,则允许浏览器显示保存对话框。

登录页面还使用“我的设备”复选框设置,以分别在选中或不选中时允许查看列表或不查看列表。无论“我的设备”设置如何,该保存列表都永远不会显示在此页面上,因为这将导致服务器上的用户密码和浏览器中的用户密码不同步,并阻止所有者使用“自动” -“”成功登录到我的Web应用程序。

下面的页面不会显示该列表,也不会显示该列表,但是当输入新的/未保存的用户名/密码组合或更改的设置时,它也不总是显示保存对话框。

这是一个简化的帐户用户创建/编辑页面示例,该示例在Google Chrome,microsoft Edge和Firefox中正确隐藏了该列表,并在选中“我的设备”复选框时多次显示保存对话框。但是,在microsoft Internet Explorer中,永远不会显示保存对话框:

<!DOCTYPE html>
<html lang="en">
  <!--

      How to turn off form autocompletion
      https://developer.mozilla.org/en-US/docs/Web/Security/Securing_your_site/Turning_off_form_autocompletion#Preventing_autofilling_with_autocompletenew-password

      The HTML autocomplete attribute
      https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/autocomplete

  -->
  <head>
    <meta charset="UTF-8">
    <title>username-Password Test Edit html</title>

    <!-- Dot-Font used to simulate the password type input element -->

    <link type="text/css" rel="stylesheet"
          href="https://cdn.rawgit.com/noppa/text-security/master/dist/text-security-disc.css">
    <script src="https://cdn.jsdelivr.net/npm/ua-parser-js@0/dist/ua-parser.min.js"></script>
    <style>
      * { font-size: x-large; font-family: Arial; }

      /* Show placeholder in normal text */

      .password_empty { font-family: inherit; }

      /* Show value as dots */

      .password_not_empty { font-family: 'text-security-disc'; }

      .column1 { position: absolute; left:  30px; }
      .column2 { position: absolute; left: 190px; top: 0; }

      textarea,input[type="email"],input[type="password"],input[type="text"] { height: 22px; width: 250px; padding-left: 2px; }
    </style>
  </head>
  <body onload="pageLoad();">
    <p id="message" style="opacity: 0;">
      Please use the Submit button to save your information.
    </p>
    <form action="username_Password_Test.php" method="post" autocomplete="off"
          onsubmit="return submitit();">

      <!--
        Hidden username and Password input 'honey-pot' elements for the browser to notice,so that it doesn't show the usernames/passwords list.
      -->

      <div id="username_password_div" style="display: none;">
        <input type="text" id="user_name" name="user_name"
               placeholder="username" tabIndex=-1
               autocomplete="on" />
        <input type="password" id="pass_word" name="pas_word"
               placeholder="password" tabIndex=-1
               autocomplete="new-password" />
      </div>

      <br />
      <label class="column1">
        Full Name:
        <input type="text" id="fullname" name="fullname" tabIndex=1
               autocomplete="off"
               class="column2"
               placeholder="Enter your full name"
               value="Test Me" />
      </label><br />
      <br />
      <label class="column1">
        Email:
        <input type="email" id="email" name="email" class="column2" tabIndex=2
               autocomplete="off"
               placeholder="Enter your email"
               value="test.me@email.web" />
      </label><br />
      <br />
      <label class="column1" title="Check if this is your personal device.">
        Your device:
        <span class="column2"
              style="white-space: nowrap;">
          <input type="checkbox" id="your_device" name="your_device" tabIndex=-1
                 autocomplete="off"
                 style="margin: 3px 0;"
                 value="yes" />
          (Leave unchecked for strict account protections.)
        </span>
      </label><br />
      <br />
      <label class="column1">
        username:
        <input type="text" id="username" name="username" tabIndex=3
               autocomplete="off"
               class="column2"
               placeholder="Enter a username"
               value="" />
      </label><br />
      <br />
      <label class="column1">
        Password:
        <input type="text" id="password" name="password" tabIndex=4
               autocomplete="off"
               class="column2 password_empty"
               placeholder="Enter a password"
               oninput="set_password_Classname();"
               value="" />
      </label><br />
      <label class="column1" style="margin-top: 4px;">
        Show password?
        <input type="checkbox" id="view_hide_password" tabIndex=-1
               class="column2" style="margin: 7px 0 0 0;"
               onclick="set_password_Classname(); password.focus();" />
      </label><br />
      <br />
      <button id="submitForm" class="column1" >Submit</button><br /><br />
    </form>
    <script>
      function pageLoad() {
        var labels                 = document.querySelectorAll( 'label' );

        var inputs,input;

        // Create global variables ...

        window.activeElement      =
        window.last_activeElement =  null;

        window.username            = document.getElementById( 'username' );
        window.password            = document.getElementById( 'password' );
        window.view_hide_password  = document.getElementById( 'view_hide_password' );
        window.submit              = document.getElementById( 'submit' );

        //
        // Track which elements get the focus in the window.activeElement - used for
        // IE/Edge to tell what element has the focus when the form is submitted,// which sets the document.activeElement to the form when the form is submitted,// thus preventing the form submit submitit function to check which element
        // actually has the focus.
        //

        document.addEventListener( 'focus',setfocus,true );
        document.addEventListener( 'focusout',unsetfocus,true );

        set_password_Classname();

        setfocus( username );

      } // End of pageLoad() function.

      function setfocus( target ) {
        var target_wtx_context,activeElement_wtx_context;

        //
        // Is the target parameter missing or it can't be focused on,then use the
        // event's target as the element to be focused on ...
        //

        target = ( ( ( target !== undefined ) && ( target.autofocus !== undefined ) )
                   ? target
                   : ( ( event !== undefined ) &&
                       ( event.target !== undefined ) &&
                       ( event.target.autofocus !== undefined )
                       ? event.target
                       : null ) );

        //
        // Get the target's wtx-context,unless the target is the submit button because
        // they don't have them.
        //

        if( ( target.nodename !== 'BUTTON' ) || ( target.id !== 'submitForm' ) ) {

          target_wtx_context        = getWTXContext( target );

          //
          // If the target has a wtx-context,then set the activeElement's
          // wtx-context.
          //

          if( target_wtx_context ) {

            activeElement_wtx_context = ( ( activeElement )
                                          ? activeElement.getattribute( 'wtx-context' )
                                          : null );

          } // End of if( target_wtx_context ) ...

        } // End of if( ( target.nodename !== 'BUTTON' ) ||
          //            ( target.id !== 'submitForm' ) ) ...

        //
        // If the submit button or the current target and the activeElement aren't the
        // same,then set the activeElememt to the current target ...
        //

        if( ( ( target.nodename === 'BUTTON' ) &&
              ( target.id === 'submitForm' ) ) ||
            ( ( target_wtx_context !== activeElement_wtx_context ) &&
              ( isFocusable( target ) ) ) ) {

          activeElement = target;

          // Focus on the current target,if it isn't the submit button ...

          if( ( target.nodename !== 'BUTTON' ) ||
              ( target.id !== 'submitForm' ) ) {

            target.focus();

          }
          else {

            submitit();

          } // End of if( ( target.nodename !== 'BUTTON' ) ||
            //            ( target.id !== 'submitForm' ) ) ...
            //        else ...

        }
        else if( last_activeElement ) {

          // The current element and the activeElement are the same.

          activeElement = last_activeElement;

        }
        else {

          activeElement = document.active_Element;

        } // End of if( ( ( target.nodename === 'BUTTON' ) &&
          //              ( target.id === 'submitForm' ) ) ||
          //            ( ( target_wtx_context !== activeElement_wtx_context ) &&
          //              ( isFocusable( target ) ) ) ) ...
          //        else if( last_activeElement ) ... else ...

      } // End of setfocus( target ) function.

      function getWTXContext( target ) {
        //
        // The wtx-context attribute that the Google Chrome browser adds to many
        // elements is useful for comparing elements rather than the
        // 'fields/values' in element objects,but not all browsers add the wtx-content
        // attribute,so this function is used to create a unique value when the
        // getattribute( 'wtx-content' ) function-call returns a null value.
        //

        var wtx_context =  ( ( target !== null )
                             ? target.getattribute( 'wtx-context' )
                             : null );

        return ( wtx_context
                 ? wtx_context
                 : ( ++getWTXContext.counter ).toString() + '-wtx' );
      } // End of getWTXContext( target )  function.
      getWTXContext.counter = 1;

      function unsetfocus() {
        var target = event.target;

        if( isFocusable( target ) ) {

          last_activeElement = target;

        } // End of if( isFocusable( target ) ) ...

      } // End of unsetfocus() function.

      function isFocusable( target ) {
        return !( ( target.nodename == 'BODY' ) ||
                  ( target.nodename == 'DIV' ) ||
                  ( target.nodename == 'SPAN' ) )
      } // End of isFocusable( target ) function.

      function set_password_Classname() {
        //
        // Toggle between the normal text class and the dot-font in the pseudo-
        // password input "password" type text element.  This allows the user to
        // view/hide the password value that they type into the input field.
        // Additionally,the password-empty allows the placeholder to be readable
        // when the pseudo- password input field doesn't contain a value.
        //

        var message     = document.getElementById( 'message' );
        var normal_text = 'password_empty';

        // Remove the password_{not_}empty class ...

        if( password.classList.contains( 'password_empty' ) ) {

          password.classList.remove( 'password_empty' );

        }
        else if( password.classList.contains( 'password_not_empty' ) ) {

          password.classList.remove( 'password_not_empty' );

        } // End of if( password.classList.contains( 'password_empty' ) ) ...
          //        else if( password.classList.contains( 'password_not_empty' ) ) ...

        if( view_hide_password !== null ) {

          if( !view_hide_password.checked ) {

            password.classList.add( ( password.value.trim().length > 0 )
                                    ? 'password_not_empty'
                                    : 'password_empty' );

          }
          else {

            // Show regular text in the password field ...

            password.classList.add( normal_text );

            password.type = 'text';

          } // End of if( !view_hide_password.checked ) ... else ...

        } // End of if( ( view_hide_password !== null ) ...

      } // End of set_password_Classname() function.

      function submitit() {
        var pass_word,user_name;

        if( activeElement &&
            ( activeElement.nodename === 'BUTTON' ) &&
            ( activeElement.id === 'submitForm' ) ) {


          if( document.getElementById( 'your_device' ).checked ) {

            //
            // Make the pseudo-password input type text element a real password field
            // so that the browser will display the save-dialog when the username and
            // password values haven't been saved before or have been changed.
            //

            password.type = 'password';

          } // End of if( document.getElementById( 'your_device' ).checked ) ...

          // The following errors,saying that submit() isn't a function.

          // activeElement.form.submit();

          // This works and submits the form ...

          ( Object.getPrototypeOf( activeElement.form ).submit ).
          call( activeElement.form );

        }
        else {

          // The form is being submitted,but the activeEement isn't the submit button.

          //
          // Display a message telling the user to use the submit button to submit the
          // form.
          //

          if( message.timer ) clearInterval( message.timer );

          message.style.opacity = 1;  // Full opacity.
          message.duration      = 10; // Start from 10,subtract 1 every 1/8 second.
          message.timer         = setInterval(

                 function() {
                   var currentOp = getcomputedStyle( message ).
                                   getPropertyValue( 'opacity' );
                   var duration  = parseFloat( message.duration );

                   if( duration > 0 )

                     message.duration = ( duration - 1 ).toString();

                   else {

                     if( currentOp > 0 )

                       currentOp -= 0.1;

                     else {

                       currentOp = 0;
                       clearInterval( message.timer );

                    } // End of if( currentOp > 0 ) ...
                      //        else ...

                    message.style.opacity = currentOp.toString();

                  } // End of if( duration = > 0 ) ...
                    //        else ...

                 },125 );

        } // End of if( activeElement &&
          //            ( activeElement.nodename === 'BUTTON' ) &&
          //            ( activeElement.id === 'submitForm' ) ) ...

        return false;
      } // End of submitit() function.
    </script>
  </body>
</html>

谢谢

rzf018575 回答:在IE中,如何使用javascript控制显示浏览器的已保存用户名/密码列表和“保存用户名/密码”对话框?

暂时没有好的解决方案,如果你有好的解决方案,请发邮件至:iooj@foxmail.com
本文链接:https://www.f2er.com/3120280.html

大家都在问