浏览器自动填充登录用户名和密码,如何清除

news2024/11/19 13:20:24

文章目录

    • 刷新网页的时候浏览器会自动填充用户名和密码
    • 刷新之后效果图
    • 解决方案
      • 完整的login.vue代码
      • 核心代码原理(添加 readonly 和监听 focus 事件)

刷新网页的时候浏览器会自动填充用户名和密码

在这里插入图片描述

刷新之后效果图

在这里插入图片描述

解决方案

完整的login.vue代码

<template>
  <div class="login">
    <el-card>
      <h2 class="title"  style="text-align: center; font-weight: bold; color: #707070;">数字化监管平台</h2>
      <el-tabs v-model="activeName" @tab-click="handleClick" stretch>
        <el-tab-pane label="机构和姓名登录" name="first">
          <div class="form-container">
            <el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form">

            <el-form-item label="" prop="deptId">
              <treeselect class="el-treeselect" v-model="loginForm.deptId" :options="deptOptions" :show-count="true"
                          placeholder="请选择归属机构"/>
              <svg-icon slot="prefix" icon-class="user" class="el-input__icon input-icon"/>
            </el-form-item>

            <el-form-item prop="nickName">
              <el-input
                v-model="loginForm.nickName"
                type="text"
                auto-complete="off"
                placeholder="姓名"
                :readonly="isReadOnly"
                @focus="handleFocus"
              >
                <svg-icon slot="prefix" icon-class="user" class="el-input__icon input-icon"/>
              </el-input>
            </el-form-item>
            <el-form-item prop="password">
              <el-input
                v-model="loginForm.password"
                type="password"
                auto-complete="off"
                placeholder="密码"
                @keyup.enter.native="handleLogin"
                :readonly="isReadOnly"
                @focus="handleFocus"
              >
                <svg-icon slot="prefix" icon-class="password" class="el-input__icon input-icon"/>
              </el-input>
            </el-form-item>
            <el-form-item prop="code" v-if="captchaEnabled">
              <el-input
                v-model="loginForm.code"
                auto-complete="off"
                placeholder="验证码"
                style="width: 63%"
                @keyup.enter.native="handleLogin"
              >
                <svg-icon slot="prefix" icon-class="validCode" class="el-input__icon input-icon"/>
              </el-input>
              <div class="login-code">
                <img :src="codeUrl" @click="getCode" class="login-code-img"/>
              </div>
            </el-form-item>
            <el-form-item style="width:100%;">
              <el-button
                :loading="loading"
                size="medium"
                type="primary"
                style="width:100%;"
                @click.native.prevent="handleLoginByOrg"
              >
                <span v-if="!loading">登 录</span>
                <span v-else>登 录 中...</span>
              </el-button>
            </el-form-item>
          </el-form>
          </div>
        </el-tab-pane>

        <el-tab-pane label="用户名登录" name="second">
          <el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form">
            <el-form-item prop="username">
              <el-input
                v-model="loginForm.username"
                type="text"
                auto-complete="off"
                placeholder="账号"
                :readonly="isReadOnly"
                @focus="handleFocus"
              >
                <svg-icon slot="prefix" icon-class="user" class="el-input__icon input-icon"/>
              </el-input>
            </el-form-item>
            <el-form-item prop="password">
              <el-input
                v-model="loginForm.password"
                type="password"
                auto-complete="off"
                placeholder="密码"
                @keyup.enter.native="handleLogin"
                :readonly="isReadOnly"
                @focus="handleFocus"
              >
                <svg-icon slot="prefix" icon-class="password" class="el-input__icon input-icon"/>
              </el-input>
            </el-form-item>
            <el-form-item prop="code" v-if="captchaEnabled">
              <el-input
                v-model="loginForm.code"
                auto-complete="off"
                placeholder="验证码"
                style="width: 63%"
                @keyup.enter.native="handleLogin"
              >
                <svg-icon slot="prefix" icon-class="validCode" class="el-input__icon input-icon"/>
              </el-input>
              <div class="login-code">
                <img :src="codeUrl" @click="getCode" class="login-code-img"/>
              </div>
            </el-form-item>
            <el-form-item style="width:100%;">
              <el-button
                :loading="loading"
                size="medium"
                type="primary"
                style="width:100%;"
                @click.native.prevent="handleLogin"
              >
                <span v-if="!loading">登 录</span>
                <span v-else>登 录 中...</span>
              </el-button>
              <div style="float: right;" v-if="register">
                <router-link class="link-type" :to="'/register'">立即注册</router-link>
              </div>
            </el-form-item>
          </el-form>
          <!--  底部  -->
          <!-- <div class="el-login-footer">
            <span>Copyright © 2018-2023 ruoyi.vip All Rights Reserved.</span>
          </div> -->
        </el-tab-pane>
      </el-tabs>
    </el-card>

  </div>

</template>

<script>
  import {getCodeImg} from "@/api/login";
  import Cookies from "js-cookie";
  import {encrypt, decrypt} from '@/utils/jsencrypt';
  import {deptTreeSelect} from "@/api/system/user";
  import Treeselect from "@riophae/vue-treeselect";
  import "@riophae/vue-treeselect/dist/vue-treeselect.css";
  import {Message} from 'element-ui'

  export default {
    name: "Login",
    components: {Treeselect},
    data() {
      return {
        codeUrl: "",
        loginForm: {
          username: "",
          password: "",
          rememberMe: false,
          code: "",
          uuid: ""
        },
        loginRules: {
          username: [
            {required: true, trigger: "blur", message: "请输入您的账号"}
          ],
          password: [
            {required: true, trigger: "blur", message: "请输入您的密码"}
          ],
          code: [{required: true, trigger: "change", message: "请输入验证码"}]
        },
        loading: false,
        // 验证码开关
        captchaEnabled: true,
        // 注册开关
        register: false,
        redirect: undefined,
        activeName: 'first',
        // 部门树选项
        deptOptions: undefined,
        isReadOnly: true
      };
    },
    watch: {
      $route: {
        handler: function (route) {
          this.redirect = route.query && route.query.redirect;
        },
        immediate: true
      }
    },
    created() {
      this.getDeptTree();
      this.getCode();
    },
    methods: {
      getCode() {
        getCodeImg().then(res => {
          this.captchaEnabled = res.captchaEnabled === undefined ? true : res.captchaEnabled;
          if (this.captchaEnabled) {
            this.codeUrl = "data:image/gif;base64," + res.img;
            this.loginForm.uuid = res.uuid;
          }
        });
      },
      handleLogin() {
        this.$refs.loginForm.validate(valid => {
          if (valid) {
            this.loading = true;
            if (this.loginForm.rememberMe) {
              Cookies.set("username", this.loginForm.username, {expires: 30});
              Cookies.set("password", encrypt(this.loginForm.password), {expires: 30});
              Cookies.set('rememberMe', this.loginForm.rememberMe, {expires: 30});
            } else {
              Cookies.remove("username");
              Cookies.remove("password");
              Cookies.remove('rememberMe');
            }
            this.$store.dispatch("Login", this.loginForm).then(() => {
              this.$router.push({path: this.redirect || "/"}).catch(() => {
              });
            }).catch(() => {
              this.loading = false;
              if (this.captchaEnabled) {
                this.getCode();
              }
            });
          }
        });
      },
      handleLoginByOrg() {
        //校验
        if (!this.loginForm.nickName) {
          Message.info("用户名称不能为空!");
          return;
        }
        if (!this.loginForm.deptId || this.loginForm.deptId === undefined) {
          Message.info("请选择机构名称!");
          return;
        }
        if (!this.loginForm.password) {
          Message.info("密码不能为空!");
          return;
        }

        this.$refs.loginForm.validate(valid => {
          if (valid) {
            this.loading = true;
            if (this.loginForm.rememberMe) {
              Cookies.set("deptId", this.loginForm.deptId, {expires: 30});
              Cookies.set("nickName", this.loginForm.nickName, {expires: 30});
              Cookies.set("username", this.loginForm.username, {expires: 30});
              Cookies.set("password", encrypt(this.loginForm.password), {expires: 30});
              Cookies.set('rememberMe', this.loginForm.rememberMe, {expires: 30});
            } else {
              Cookies.remove("nickName");
              Cookies.remove("username");
              Cookies.remove("password");
              Cookies.remove('rememberMe');
            }
            this.$store.dispatch("LoginByOrg", this.loginForm).then(response => {
              console.log('response', response);
              Message.info(response)
              this.$router.push({path: this.redirect || "/"}).catch(() => {
              });
              this.loading = false;
            }).catch(() => {
              this.loading = false;
              if (this.captchaEnabled) {
                this.getCode();
              }
            });
          }
        });
      },
      handleClick(tab, event) {
        console.log(tab, event);
      },
      /** 查询部门下拉树结构 */
      getDeptTree() {
        deptTreeSelect().then(response => {
          this.deptOptions = response.data;
        });
      },
      handleFocus(event) {
        this.isReadOnly = false;
        // 可能还需要在某些情况下重新聚焦,以确保输入框获得焦点
        // event.target.blur();
        // event.target.focus();
      },
    }
  };
</script>

<style rel="stylesheet/scss" lang="scss">
  .login {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    height: 100%;
    background-image: url("../assets/images/login-new.png");
    background-size: cover;
  }

  .el-tabs {
    background-color: #ffffff; /* 设置底色为白色 */
  }

  .login-form {
    border-radius: 6px;
    background: #ffffff;
    width: 400px;
    padding: 25px 25px 5px 25px;

    .el-input {
      height: 38px;

      input {
        height: 38px;
      }
    }

    .input-icon {
      height: 39px;
      width: 14px;
      margin-left: 2px;
    }
  }

  .login-tip {
    font-size: 13px;
    text-align: center;
    color: #bfbfbf;
  }

  .login-code {
    width: 33%;
    height: 38px;
    float: right;

    img {
      cursor: pointer;
      vertical-align: middle;
    }
  }

  .login-code-img {
    height: 38px;
  }

  .form-container {
    overflow-y: auto;
  }


</style>

核心代码原理(添加 readonly 和监听 focus 事件)

用户名和密码字段即使没有赋值也出现浏览器自动填充的情况,可以采用以下方法来禁止这一行为:

  1. 使用 auto-complete 属性(实测并没有生效):
    对于 el-input 组件,你应该将 auto-complete 属性设置为 "new-password",即使对于非密码字段也是如此,因为某些浏览器可能对常见的字段名有所识别并尝试自动填充。例如:

    <el-input v-model="username" auto-complete="new-password"></el-input>
    <el-input v-model="password" type="password" auto-complete="new-password"></el-input>
    
  2. 添加 readonly 和监听 focus 事件 (实测有效):
    初始时设置输入框为只读(readonly),并在获得焦点时移除只读属性,这可以阻止某些浏览器的自动填充功能。需要在组件的 focus 事件中移除 readonly

    <el-input
      v-model="username"
      auto-complete="new-password"
      :readonly="isReadOnly"
      @focus="handleFocus"
    ></el-input>
    
    <script>
    export default {
      data() {
        return {
          username: '',
          isReadOnly: true,
        };
      },
      methods: {
        handleFocus(event) {
          this.isReadOnly = false;
          // 可能还需要在某些情况下重新聚焦,以确保输入框获得焦点
          // event.target.blur();
          // event.target.focus();
        },
      },
    };
    </script>
    

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1890527.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

linux系统主机查看系统日志(可查看被执行命令和远程登录等)

linux系统中&#xff0c;在/var/log/messages日志文件中&#xff0c;会记录显示系统所有运行的相关日志 如果被黑客攻击进来&#xff0c;可以在此日志做排查&#xff01; 例如&#xff1a;记录远程登录日志 记录执行命令日志

问题集锦2

1.商品详情和切换数据&#xff0c;要做好来源区分 今天&#xff0c;商品切换 我可以不可以&#xff0c;不选择传递空&#xff0c;导致if没有走到 2.查价格&#xff0c;用用户传递的

Rocky Linux 9 系统OpenSSH CVE-2024-6387 漏洞修复

Rocky Linux 9系统 OpenSSH CVE-2024-6387 漏洞修复 1、漏洞修复2、修复思路3、修复方案3.1、方案一3.2、方案二 4、总结5、参考 1、漏洞修复 CVE-2024-6387&#xff1a;regreSSHion&#xff1a;OpenSSH 服务器中的远程代码执行&#xff08;RCE&#xff09;&#xff0c;至少在…

如何选择适合自己的虚拟化技术?

虚拟化技术已成为现代数据中心和云计算环境的核心组成部分。本文将帮助您了解如何选择适合自己需求的虚拟化技术&#xff0c;以实现更高的效率、资源利用率和灵活性。 理解虚拟化技术 首先&#xff0c;让我们了解虚拟化技术的基本概念。虚拟化允许将一个物理服务器划分为多个虚…

机器人控制系列教程之Delta机器人奇异性分析

并联机器人奇异性 对于并联机构的奇异性问题比串联机构复杂。某些位形机构会失去自由度&#xff0c;某些位形机构会出现不可控自由度。其分析方法主要有几何法和代数法&#xff0c; 几何法&#xff1a; 即根据高等空间相关知识和机构中角度范围、干涉条件等推导出机构的奇异位…

LeetCode 算法:路径总和 III c++

原题链接&#x1f517;&#xff1a;路径总和 III 难度&#xff1a;中等⭐️⭐️ 题目 给定一个二叉树的根节点 root &#xff0c;和一个整数 targetSum &#xff0c;求该二叉树里节点值之和等于 targetSum 的 路径 的数目。 路径 不需要从根节点开始&#xff0c;也不需要在叶…

WPF对象样式

基本样式设置 Style 设置指定对象的属性 属性&#xff1a; TargetType 引用在哪个类型上面&#xff0c;例如Button、Textblock。。 如果在控件对象里面设置Style&#xff0c;则TargetType必须指定当前控件名 只在作用域里面有效果&#xff0c;其他的相同控件没有影响&…

【LeetCode的使用方法】

🎥博主:程序员不想YY啊 💫CSDN优质创作者,CSDN实力新星,CSDN博客专家 🤗点赞🎈收藏⭐再看💫养成习惯 ✨希望本文对您有所裨益,如有不足之处,欢迎在评论区提出指正,让我们共同学习、交流进步! 🔮LeetCode的使用方法 🔮LeetCode 是一个在线编程平台,广泛…

RPM包管理-rpm命令管理

1.RPM包命令原则 所有的rpm包都在光盘中 例&#xff1a;httpd-2.2.15-15.e16.centos.1.i686.rpm httpd 软件包名 2.2.15 软件版本 15 软件发布的次数 e16.centos 适合的Linux平台 i686 适合的硬件平台…

粒子扩展卡尔曼滤波|MATLAB代码

粒子滤波PF与扩展卡尔曼滤波EKF结合 下载链接:https://download.csdn.net/download/callmeup/89512392 粒子滤波 粒子滤波是一种用于估计状态变量的非线性滤波方法。它通过引入一组粒子来近似表示概率分布,从而利用蒙特卡洛方法进行状态估计。粒子滤波的主要思想是根据系统…

新手教学系列——慎用Flask-SQLAlchemy慢日志记录

在使用 Flask-SQLAlchemy 开发应用时,了解和避免潜在的问题是非常重要的。特别是在常驻进程和循环执行任务的场景下,慢查询记录功能(SQLALCHEMYRECORDQUERIES)可能会引发严重的内存泄漏问题。本文将详细介绍这个问题,并提供解决方案,帮助你在开发过程中避免掉入这些陷阱。…

哈希表 | 哈希查找 | 哈希函数 | 数据结构 | 大话数据结构 | Java

&#x1f64b;大家好&#xff01;我是毛毛张! &#x1f308;个人首页&#xff1a; 神马都会亿点点的毛毛张 &#x1f4cc;毛毛张今天分享的内容&#x1f586;是数据结构中的哈希表&#xff0c;毛毛张主要是依据《大话数据结构&#x1f4d6;》的内容来进行整理&#xff0c;不…

3D Gaussian Splatting代码中的train和render两个文件代码解读

现在来聊一聊训练和渲染是如何进行的 training train.py line 31 def training(dataset, opt, pipe, testing_iterations, saving_iterations, checkpoint_iterations, checkpoint, debug_from):# 初始化第一次迭代的索引为0first_iter 0# 准备输出和日志记录器tb_writer p…

0703_ARM7

练习&#xff1a; 封装exti&#xff0c;cic初始化函数 //EXTI初始化 void hal_key_exti_init(int id,int exticr,int mode){//获取偏移地址int address_offset (id%4)*8;//获取寄存器编号int re_ser (id/4)1;//printf("address_offset%d,re_ser%d\n",address_o…

苹果手机怎么刷机?适合小白的刷机办法!

自己的苹果手机用时间长了&#xff0c;有些人想要为自己的手机重新刷新一下&#xff0c;但又不知道怎么刷机。不要慌现在就来给大家详细介绍一下苹果手机怎么刷机&#xff0c;希望可以帮助到大家。 iPhone常见的刷机方式&#xff0c;分为iTunes官方和第三方软件两种刷机方式。 …

基于Web技术的教育辅助系统设计与实现(SpringBoot MySQL)+文档

&#x1f497;博主介绍&#x1f497;&#xff1a;✌在职Java研发工程师、专注于程序设计、源码分享、技术交流、专注于Java技术领域和毕业设计✌ 温馨提示&#xff1a;文末有 CSDN 平台官方提供的老师 Wechat / QQ 名片 :) Java精品实战案例《700套》 2025最新毕业设计选题推荐…

强行仅用time.localtime制作“日历牌”——全程记录“顶牛”“调戏”我的AI学习搭子

强行只用time.localtime制作“日历牌”&#xff0c;码好代码试炼通过&#xff0c;想榨取ai智能优化算法&#xff0c;结果失败。本文详细记录“顶牛”全过程。 (笔记模板由python脚本于2024年07月01日 19:16:26创建&#xff0c;本篇笔记适合喜欢python&#xff0c;喜欢搞“事儿”…

p2p、分布式,区块链笔记: 通过libp2p的Kademlia网络协议实现kv-store

Kademlia 网络协议 Kademlia 是一种分布式哈希表协议和算法&#xff0c;用于构建去中心化的对等网络&#xff0c;核心思想是通过分布式的网络结构来实现高效的数据查找和存储。在这个学习项目里&#xff0c;Kademlia 作为 libp2p 中的 NetworkBehaviour的组成。 以下这些函数或…

controller不同的后端路径对应vue前端传递数据发送请求的方式,vue请求参数 param 与data 如何对应后端参数

目录 案例一&#xff1a; 为什么使用post发送请求&#xff0c;参数依旧会被拼接带url上呢&#xff1f;这应该就是param 与data传参的区别。即param传参数参数会被拼接到url后&#xff0c;data会以请求体传递 补充&#xff1a;后端controller 参数上如果没写任何注解&#xff0c…

Redis中hash类型的操作命令(命令的语法、返回值、时间复杂度、注意事项、操作演示)

文章目录 字符串和哈希类型相比hset 命令hget 命令hexistshdelhkeyshvalshgetallhmgethlenhsetnxhincrbyhincrbyfloat 字符串和哈希类型相比 假设有以下一种场景&#xff1a;现在要在 Redis 中存储一个用户的基本信息(id1、namezhangsan、age17)&#xff0c;下图表示使用字符串…