javascript - 使用 cookie 启用 4 位密码自动填充

标签 javascript cookies

我有一个简单的表格,需要输入一个 4 位数的 PIN 码。但是,我还想在用户再次返回网站时使用 JS cookie 自动填充该 PIN 码。

JS:

function loginCheck() {
    var pinCode = document.getElementById("pinCode").value;
        if (pinCode.match(/^[0-9]+$/) != null) {
            if (pinCode.length == 4) {
                function setCookie(cname, cvalue) {
                    document.cookie = cname + "=" + cvalue + ";"
                }
                function getCookie(cname) {
                    var name = cname + "=";
                    var ca = document.cookie.split(';');
                    for(var i = 0; i < ca.length; i++) {
                        var c = ca[i];
                        while (c.charAt(0) == ' ') {
                            c = c.substring(1);
                        }
                        if (c.indexOf(name) == 0) {
                            return c.substring(name.length, c.length);
                        }
                    }
                    return "";
                }
                function checkCookie() {
                    var pinCode = document.getElementById("pinCode").value;
                    var userPIN = getCookie("userPIN");
                    if (userPIN != "") {
                        pinCode.value = userPIN;
                    } else {
                        setCookie("username", userPIN);
                    }
                }
                checkCookie();
            } else {
                document.getElementById("rightorwrong").innerHTML = "Not 4 digits!";
            }
        } else {
            document.getElementById("rightorwrong").innerHTML = "Not a number!";
        }
}

HTML:

<div id = "validation">
            <form id = "validationForm" target = "frame">
                <fieldset>
                    <label for = "pass">Password:</label><br  />
                    <input type = "text" id = "pass" name = "pass"  /><br  />
                    <label for = "pinCode">4-digit PIN:</label><br  />
                    <input type = "text" id = "pinCode" name = "pinCode"  /><br  />
                    <input type = "submit" value="Log In" onclick = "loginCheck()"  />
                </fieldset>
            </form>
        </div>
        <p id = "rightorwrong"></p>

我知道这段代码有一些错误。

  • checkCookie() 函数中,如果用户存储了 cookie,那么我不完全确定如何检索他们首先输入的 PIN。
  • 在函数内部定义函数,并通过简单地执行 checkCookie(); 调用它们,而不做其他任何事情,通常是不好的做法。
  • 当我运行 checkCookie(); 时,它只执行 if 语句的第一部分,而不执行第二部分。我不确定为什么,也想不通。
  • 代码一般可能有一些错误。我从 here 修改了一个 cookies 脚本但它似乎不起作用。

我对 cookie 的概念还很陌生,并且仍在努力学习它们。分步解释会更有帮助。

非常感谢您的帮助,TIA。

最佳答案

对于 cookie,我使用带有 set/getVal 方法的“simpleCookie”对象来读取或保存 cookie。

例如:

simpleCookie.setVal( 'my cookie', 'ab/kjf;c', 3 )

let valueX = simpleCookie.getVal('my cookie'))  // return 'ab/kjf;c'
 
simpleCookie.setVal( 'my cookie', '', -1)  remove the cookie

此对象是通过 IIEF function 实现的, 我强烈建议您使用 mozilla 文档

由于存在自动表单验证,我不再使用文本框来指示输入错误,但我稍微改变了它的“正常”用法,因为我发现它非常有限制,正如您将在我的代码中看到的那样。

在您的问题基础上,您只需找到输入的名称与可能的同名 cookie 之间的匹配项,然后在表单有效时保存此 cookie。

哦,我还放了一些 css 来简化编写 html(不再需要 <br>)

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>login form</title>
  <style>
    fieldset { margin: 1em; width: 15em; }
    fieldset * { display: block; float: left; clear: both; margin-top: 0.2em; }
    fieldset label { margin-top: 0.7em; }
    fieldset button { margin-top: 2em; }
    fieldset button:last-of-type { clear: none; float: right; }
   </style>
</head>
<body>
  <form id="login-form" action="">
    <fieldset>
      <label>Name:</label> 
      <input type="text" name="name" autocomplete="off"  pattern="[A-Za-z0-9]{1,20}"> 
      <label>Password:</label> 
      <input type="password" name="pass" pattern="[A-Za-z0-9]{1,20}"> 
      <label>4-digit PIN:</label> 
      <input type="text" name="pinCode" autocomplete="off" pattern="[0-9]{4}"> 
      <button type="reset">clear</button>
      <button type="submit">Log In</button>
    </fieldset>
  </form>

  <script src="simpleCoolie.js"></script> <!-- the cookie object (IIFE) -->
  <script src="login_form.js"></script>
</body>
</html>

simpleCoolie.js:

// the cookie object (IIFE)
const simpleCookie = (function()
  {
  const OneDay_ms = 24 *60 *60 *1000  // one Day in milliseconds 
  return { 
    setVal:(cName, cValue='', exDays=10)=>  // 10 days is default cookie recovery, 
      {                                    // negative value remove the cookie
      cName  = encodeURIComponent(cName.trim())
      cValue = encodeURIComponent(cValue.trim())
      if (cName)
        {
        let dte = new Date()
        dte.setTime(dte.getTime() + (exDays *OneDay_ms))          
        document.cookie = `${cName}=${cValue};expires=${dte.toUTCString()};SameSite=Strict;path=/`
      } }
  , getVal:cName=>
      {
      cName = encodeURIComponent(cName.trim())
      let xCookie = document.cookie.split('; ').find(x=>x.startsWith(`${cName}=`))
      return xCookie ? decodeURIComponent(xCookie.split('=')[1]) : ''
    } }
  })()

登录表单.js:

const formLogin        = document.getElementById('login-form')
  ,   msgErrorDuration = 5000
  ,   checkInputs =
        [...formLogin.querySelectorAll('input[pattern]')]
          .map(el=>
            {
            let pattern = el.pattern
            el.removeAttribute('pattern')
            return { name:el.name, pattern } 
            });

// generic set checking for report validyty
const getCheckingValidity=(formElement, patternValue)=>
  {
  formElement.pattern  = patternValue
  formElement.required = true
  return formElement.reportValidity()  
  }
// generic checking remove after delay 
const unCheckElement=(formElement,isOK)=>
  {
  formElement.removeAttribute('pattern')
  formElement.required = false

  if(!isOK)
    {
    formElement.setCustomValidity('')
    if(document.activeElement === formElement )  // bugg fix: Firefox doesnt remove error message after delay 
      {                                         // (other browser do)
      formElement.blur();                      // double flip focus
      formElement.focus();                    // --> will remove message bubble
      }
    }
  }

// client-side form validation mecanism to get error message for each input
formLogin.name.oninvalid=_=>
  {
  formLogin.name.setCustomValidity('Please enter a name')
  setTimeout(unCheckElement, msgErrorDuration, formLogin.name, false)
  }
formLogin.pass.oninvalid=_=>
  {
  formLogin.pass.setCustomValidity("can't do anything without password !")
  setTimeout(unCheckElement, msgErrorDuration, formLogin.pass, false)
  }
formLogin.pinCode.oninvalid=_=>
  {
  if (formLogin.pinCode.value==='')
    { formLogin.pinCode.setCustomValidity("PIN code can't be empty !") }
  else
    { formLogin.pinCode.setCustomValidity('PIN code must be 4 digits') }
  setTimeout(unCheckElement, msgErrorDuration, formLogin.pinCode, false)
  }

formLogin.onsubmit=e=>
  {
  let validForm = true 

  for (let Elm of checkInputs)  
    {
    validForm = validForm && getCheckingValidity(formLogin[Elm.name], Elm.pattern )
    if (validForm)
      { unCheckElement(formLogin[Elm.name], true) }
    else break 
    } 
  if (validForm)
    { simpleCookie.setVal( formLogin.name.value, formLogin.pinCode.value ) }
  else
    { e.preventDefault() } // disable form submiting
  }

formLogin.name.oninput=()=>  // check for cookie pin code on name
  {
  formLogin.pinCode.value = simpleCookie.getVal(formLogin.name.value)
  }

2009年, session /localStorage到了,可以代替cookies,特别适合这种用途。

为了不必重做之前的所有逻辑,我在这里创建了一个名为 pseudoCookie 的模块,它实际上使用了 localStorage

这里是完整的测试代码:

// the pseudo cookie object (IIFE)
const pseudoCookie = (function()  // use localStorage 
  {
  return {
    setVal:(cName, cValue='', exDays=10)=> // negative value remove the value in localstorage
      {                          // the values are kept until your browser or your system crashes
      cName  = encodeURIComponent(cName.trim())
      cValue = encodeURIComponent(cValue.trim())
      if (cName) {
        if   (exDays < 0)  localStorage.removeItem(cName)
        else               localStorage.setItem(cName, cValue)
      } }
  , getVal:cName=>
      {
      cName = encodeURIComponent(cName.trim())
      let xCookie = localStorage.getItem(cName)
      return xCookie ? decodeURIComponent(xCookie) : ''
    } }
  })()

以及在 JS 中更改的部分:

formLogin.onsubmit=e=>
  {
  let validForm = true 

  for (let Elm of checkInputs)  
    {
    validForm = validForm && getCheckingValidity(formLogin[Elm.name], Elm.pattern )
    if (validForm)
      { unCheckElement(formLogin[Elm.name], true) }
    else break 
    } 
  if (validForm)
    { pseudoCookie.setVal( formLogin.name.value, formLogin.pinCode.value ) }
  else
    { e.preventDefault() } // disable form submiting
  }

formLogin.name.oninput=()=>  // check for cookie pin code on name
  {
  formLogin.pinCode.value = pseudoCookie.getVal(formLogin.name.value)
  }

关于javascript - 使用 cookie 启用 4 位密码自动填充,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63633918/

相关文章:

javascript - 将链接 <a> 包裹在 <div> 周围

javascript - Angularjs ng-disabled 不起作用

javascript - 在不更改值的情况下在输入字段中显示不同的值?

javascript - javascript 中事件文本区域(ckeditor)上的 Keyevent

cookies - 您可以延长 BC 中登录的 Cookie 持续时间吗?

session - 复制 JSESSIONID cookie 时防止复制 session

javascript - CSS <div> 换行错误

cookies - Google 如何知道我仍处于登录状态?

cookies - 在 wiremock 的 stub 响应中插入 cookie

node.js - 在 ExpressJs 中设置 Cookie 失败