解决谷歌浏览器form表单自动填充

本文介绍了如何在前端开发中解决谷歌浏览器自动填充form表单的问题,提供三种解决方案,并且探讨了Promise的概念和用法,以及在基于vue-element开发时如何修改element-ui组件的样式。此外,还分享了与UI设计师沟通调整组件样式的经验。

前言

时间如白驹过隙,转瞬即逝,转眼间离上次写博客也长达八个月之久了。在这与同学分开的八个月时间,我的生活也算时而成佛时而封魔了,(然而到这里我就默默的念叨一句“老司机们别想歪了呀,不是那啥前如魔,那啥后成佛,具体情况我也描述不出来,只能说生活终于还是对我下手了”!!)不过最终还算功德圆满,有幸成为了一位前端工程师。学了三年半java后端,以及实习了半年Android及全栈的我,最后居然去做前端了,也算是人生的一大转折了。基于目前基础太差,所以记录一些前端基础知识咯,方便自己的同时也想着能帮助他人,我也知道有bug的感觉是怎样的,反正不好受。虽然标题只是解决谷歌form表单的填充,but!!后面还有ES6 新特性Promise用法,以及基于vue-element手脚架的组件样式的修改。

取消谷歌浏览器form表单的填充

首先我来给大家科普一下下,谷歌for表单填充的出发条件,一般情况是由type=“text”后面接着出现type=“password”两个表单同时出现引起的,但是肯定有例外咯,嘻嘻,其实我也不知道例外的规律是什么,反正它就是要给你填,你又不能把它怎么样了,只能从 自己的代码下手咯,解决方案,两种方式:

  1. 第一种,在你的表单上面添加两个表单类型为text,password,隐藏之,直接上代码。重点在于visibility: hidden
    <input type="text"  name="username" style="height:1px; visibility: hidden" autocomplete="off"/>
    <input type="password" name="password" style="height:1px; visibility: hidden" autocomplete="off"/>

2.第二种,设置input里面的auto-complete=“off”属性,还是上点代码咯,直观一点。这里有两点需要强调,第一点:auto-complete和autocomplete这两个,谁管用就用哪个,别问,我也不知道为啥,第二点:要是同时解决text类型下面接着password类型的表单,则需要在password类型的表单中使用auto-complete=“new-password”。

   <el-input
        ref="phonenumber"
        v-model="loginForm.phonenumber"
        placeholder="请输入手机号"
        name="phonenumber"
        type="text"
        tabindex="1"
        auto-complete="off"
      />
       <el-input
        :key="passwordType"
        ref="password"
        v-model="loginForm.password"
        :type="passwordType"
        placeholder="请输入密码"
        name="password"
        tabindex="2"
        auto-complete="new-password"
        @keyup
      />

3.若是上诉两种方法都不适用,那就试试这个吧。(讲真的,本来我两种方法都有效,使用一段时间后两种方法都无效了,让我都有种代码中邪了的感觉)
说说具体做法,在css的input中加入 &:-webkit-autofill{-webkit-text-fill-color:‘你输入框想要的颜色’},木有办法,若是浏览器非得给你填充,那么便让填充的背景色成为自己想要的颜色吧。

  input {
      	 background: transparent;
         border: 0px;
         -webkit-appearance: none;
         border-radius: 0px;
         padding: 12px 5px 12px 15px;
         color: rgba(141,141,141,1);
         height: 47px;
         caret-color: rgba(141,141,141,1);
         &:-webkit-autofill {
           -webkit-text-fill-color: rgba(141,141,141,1) !important;
           transition: background-color 5000s ease-in-out 0s;
         }
       }

Promise的理解和用法

在下思考良久,发现自己并不能讲promise说个清楚明白,更甚至于恐误人子弟,那便附上一段链接吧,廖大神讲课还是很通俗易懂的,简单转述一下吧:“promise是一个用来执行 ‘将来会执行某件事’的对象”,比自己写回调函数牛逼多了。链接如下
廖大神之promise详细介绍与用法

基于vue-element前端开发时,修改element-ui组件的样式

这个问题的开发场景是这样,如果你的网站设计没有UI的话直接用element的原生样式就差不多,毕竟大公司的产品,审美还是很符合多数人的。然而,在下也不知该说幸运还是不幸,网站的原型和UI全部有人设计了,我就只需要干点讲图片转化为代码就行,当然像我这样思想随意浪荡的小青年是觉得不会甘心被如此约束,一边想着实习的时候啥都是让我自己设计那段日子(其实那个时候真的觉得很煎熬,因为设计不出来,,,),一边联系上了UI,毕竟新人嘛,我客客气气的问道:“UI老哥,您看这个页面我这样写行不行”?,三五分钟后,老哥也温柔回复我了,“你这个不行,视觉效果太软了,这些页面都是大佬们看过敲定的,不能随便修改”。我心里有个声音一直在说着“坚持自己的想法,与他干”,but,我还是秒回了“好的,我马上改”。于是就有了这个知识点的分享。
在你需要修改element-ui组件的页面,写入下图css格式,必须记得一点不能有scoped,这里有着我对element的按钮组件的修改,只是修改了五个样式而已,不知道你们觉得多不多,我觉得还行,只是不好找啊,下面重点来了,我是如何找到他们的呢,最笨的方法往往很有效果,f12去找,如果您问我f12怎么找的话,我想您应该还不会用到这个知识点,就当看个热闹吧,f12找的时候,一般一两次是找不完的,需要改变您想要改变组件的状态,例如button就是点击,鼠标进入,点击设为不可用,点击设为不可用后移出,点击执行失败后移出,等等,只要您细心就一定能找完,其实也不用找完,只要能满足您的需求就ok了。然而这里有个小问题,我也尚未解决,就是将这些样式提取到外部css文件时,有些样式会失效,也不知是不是因为我脸黑的原因,反正不知道,就只能每个文件复制粘贴css文件了。

<style lang="scss">
  .el-button--primary {
    background-color:rgba(0,162,154,1);
    border-color:rgba(0,162,154,1)
  }
    .el-button--primary:hover {
    background-color:rgba(0,162,154,1);
    border-color:rgba(0,162,154,1)
  }
  .el-button--primary.is-disabled {
    background-color:#c5c5c5;
    border-color:#c5c5c5
  }

   .el-button--primary.is-disabled:hover {
    background-color:#c5c5c5;
    border-color:#c5c5c5
  }
  .el-button--primary:focus, .el-button--primary:hover {
    background-color:rgba(0,162,154,1);
    border-color:rgba(0,162,154,1)
  }
</style>

不说再见

好吧,夕阳西下,没钱人在加班。。。。。。。。。。。。。。。。。。

<think>我们正在开发一个谷歌浏览器扩展,用于自动填充账号密码。根据引用内容,我们知道浏览器本身有自动填充功能,但有时在非标准表单或需要特定触发时可能不工作。因此,扩展需要能够模拟用户输入,或者调用浏览器自动填充API。 然而,需要注意的是,出于安全考虑,浏览器扩展对密码字段的操作是受限的。通常,我们可以通过内容脚本(content script)在页面上注入JavaScript代码,来填充表单字段。 步骤概述: 1. 创建扩展的基本结构(manifest.json,背景脚本,内容脚本等)。 2. 在manifest.json中声明必要的权限,例如:对目标网站的访问权限、存储权限(用于保存/读取密码)等。 3. 使用内容脚本在页面加载时注入,并执行填充操作。 但是,自动填充账号密码有两种方式: a) 使用扩展的存储(例如chrome.storage)来保存用户提供的账号密码,然后在特定页面填充。 b) 调用浏览器自带的密码管理功能(即chrome自动填充)来填充。 由于引用[3]提到,浏览器自动填充后,前端可能无法立即检测到(不会触发change事件),因此我们需要在扩展填充后手动触发change事件。 这里我们主要介绍方式a,因为方式b需要与浏览器的密码管理器交互,而浏览器的密码管理器通常是由用户主动触发的(例如点击输入框时下拉选择),扩展不能直接调用。但我们可以模拟用户输入。 扩展开发步骤: 1. 创建manifest.json文件,这是扩展的配置文件。 2. 创建背景脚本(background.js)和内容脚本(content.js)。 3. 在内容脚本中,检测页面上的表单,并填充账号密码。 具体实现: 第一步:创建manifest.json ```json { "name": "自动填充扩展", "version": "1.0", "manifest_version": 3, "description": "自动填充账号密码", "permissions": [ "storage", "activeTab", "scripting" ], "background": { "service_worker": "background.js" }, "action": { "default_popup": "popup.html" }, "content_scripts": [ { "matches": ["<all_urls>"], "js": ["content.js"] } ] } ``` 第二步:创建内容脚本content.js 在这个脚本中,我们需要在页面加载完成后,查找登录表单,然后填充账号密码。这里我们假设用户已经通过扩展的弹出窗口(popup.html)保存了某个网站的账号密码。 为了简化,我们假设扩展存储中保存了特定网站的账号密码。例如,我们存储的结构为: { "example.com": { "username": "admin", "password": "123456" } } 在content.js中: ```javascript // 当页面加载完成后,尝试填充 window.addEventListener('DOMContentLoaded', function() { // 从扩展的存储中获取当前网站的账号密码 chrome.storage.local.get([window.location.hostname], function(result) { const siteData = result[window.location.hostname]; if (siteData) { // 查找用户名和密码输入框 const usernameInput = document.querySelector('input[type="text"], input[type="email"], input[name="username"]'); const passwordInput = document.querySelector('input[type="password"]'); if (usernameInput && passwordInput) { // 填充值 usernameInput.value = siteData.username; passwordInput.value = siteData.password; // 触发input和change事件,以便页面上的JavaScript能够检测到 usernameInput.dispatchEvent(new Event('input', { bubbles: true })); usernameInput.dispatchEvent(new Event('change', { bubbles: true })); passwordInput.dispatchEvent(new Event('input', { bubbles: true })); passwordInput.dispatchEvent(new Event('change', { bubbles: true })); // 如果页面有登录按钮,可以尝试自动点击?但需要谨慎,因为用户可能不想自动登录 // 所以这里我们只填充,不自动提交 } } }); }); ``` 第三步:创建弹出窗口popup.html和popup.js,用于让用户保存当前页面的账号密码。 popup.html: ```html <!DOCTYPE html> <html> <head> <style> body { width: 300px; padding: 10px; } </style> </head> <body> <h3>保存账号密码</h3> <div> <label>用户名: <input type="text" id="username"></label><br> <label>密码: <input type="password" id="password"></label><br> <button id="save">保存</button> </div> <script src="popup.js"></script> </body> </html> ``` popup.js: ```javascript document.getElementById('save').addEventListener('click', function() { const username = document.getElementById('username').value; const password = document.getElementById('password').value; if (username && password) { // 获取当前网站的hostname chrome.tabs.query({active: true, currentWindow: true}, function(tabs) { const url = new URL(tabs[0].url); const hostname = url.hostname; // 保存到扩展存储 const data = {}; data[hostname] = { username, password }; chrome.storage.local.set(data, function() { alert('保存成功!'); }); }); } else { alert('请填写完整!'); } }); ``` 第四步:创建背景脚本background.js(在manifest v3中,背景脚本改为service worker) 在这个例子中,背景脚本暂时不需要,但我们在manifest中已经声明了,所以创建一个空的background.js。 注意:以上代码只是一个简单的示例,实际应用中需要处理更复杂的情况,比如: - 一个页面可能有多个表单 - 输入框的id或name不固定,可能需要更智能的查找 - 保存密码时,用户可能想保存多个账号 此外,安全方面:存储密码时,建议加密存储,但这里为了简化没有处理。 关于引用[3]中提到的问题:浏览器自动填充后,前端可能没有触发change事件,导致登录按钮不可用。在我们的扩展中,我们填充后手动触发了input和change事件,这样应该可以解决这个问题。 但是,请注意,我们的扩展是在DOMContentLoaded事件中执行的,如果页面是动态加载表单(例如单页应用),则可能无法捕获。这时可以使用MutationObserver监听DOM变化。 扩展安装:在chrome中打开扩展管理页面(chrome://extensions/),开启开发者模式,加载已解压的扩展文件夹。 以上就是一个简单的自动填充扩展的实现。 注意:由于浏览器的安全策略,扩展不能直接访问所有网站的内容,特别是通过content_scripts注入的脚本,只能访问声明了权限的网站(在manifest.json的matches中指定)。上述例子中使用了<all_urls>,即所有网站,但实际发布时可能需要更严格的限制。 另外,存储密码有安全风险,建议使用chrome提供的加密API(例如chrome.crypto)进行加密存储。 最后,我们也可以考虑使用chrome的login API(chrome.autofill)来实现更高级的自动填充,但该API主要用于表单自动填充,且需要声明"autofill"权限。但该API目前主要用于地址等表单,不用于密码。因此,上述方法更直接。 参考资料: [^1]: 谷歌浏览器自动填充密码设置方法 [^2]: Chrome浏览器密码管理功能详解 [^3]: 浏览器自动填充后前端无法立即获取的问题 [^4]: LastPass等多浏览器密码管理工具 注意:在开发扩展时,请务必遵循谷歌浏览器的扩展开发规范,并注意用户隐私和安全。 §§相关问题§§ 1. 如何增强浏览器扩展中存储密码的安全性? 2. 如何处理动态加载页面的表单自动填充? 3. 如何在多个账号中选择填充?</think># 谷歌浏览器扩展开发:自动填充账号密码功能 ## 开发思路与核心步骤 开发谷歌浏览器扩展实现自动填充功能需要以下核心组件: 1. **manifest.json** - 扩展的配置文件 2. **内容脚本** - 在目标网页上执行自动填充操作 3. **后台脚本** - 管理密码存储和安全 4. **用户界面** - 管理保存的密码和设置 ### 1. 创建manifest.json文件 ```json { "manifest_version": 3, "name": "密码自动填充", "version": "1.0", "description": "自动填充网站登录信息", "permissions": [ "storage", "activeTab", "scripting" ], "host_permissions": [ "<all_urls>" ], "background": { "service_worker": "background.js" }, "content_scripts": [ { "matches": ["<all_urls>"], "js": ["content.js"] } ], "action": { "default_popup": "popup.html", "default_icon": { "16": "icon16.png", "48": "icon48.png" } }, "icons": { "16": "icon16.png", "48": "icon48.png", "128": "icon128.png" } } ``` ### 2. 实现内容脚本(content.js) - 自动填充逻辑 ```javascript // 监听页面加载完成 window.addEventListener('load', () => { // 获取当前域名 const hostname = window.location.hostname; // 从存储中获取该网站的登录信息 chrome.storage.local.get(['credentials'], (result) => { const credentials = result.credentials || {}; const siteCredentials = credentials[hostname]; if (siteCredentials) { fillCredentials(siteCredentials); } }); }); // 填充用户名和密码 function fillCredentials(credentials) { // 查找用户名输入框 const usernameInputs = [ ...document.querySelectorAll('input[type="text"]'), ...document.querySelectorAll('input[type="email"]'), ...document.querySelectorAll('input[id*="user"]'), ...document.querySelectorAll('input[name*="user"]') ]; // 查找密码输入框 const passwordInputs = [ ...document.querySelectorAll('input[type="password"]'), ...document.querySelectorAll('input[id*="pass"]'), ...document.querySelectorAll('input[name*="pass"]') ]; // 填充用户名 if (usernameInputs.length > 0) { usernameInputs[0].value = credentials.username; // 触发事件确保页面检测到输入变化 usernameInputs[0].dispatchEvent(new Event('input', { bubbles: true })); usernameInputs[0].dispatchEvent(new Event('change', { bubbles: true })); } // 填充密码 if (passwordInputs.length > 0) { passwordInputs[0].value = credentials.password; passwordInputs[0].dispatchEvent(new Event('input', { bubbles: true })); passwordInputs[0].dispatchEvent(new Event('change', { bubbles: true })); } // 尝试查找并提交表单 setTimeout(() => { const forms = document.querySelectorAll('form'); if (forms.length > 0) { forms[0].submit(); } }, 500); } ``` ### 3. 实现后台脚本(background.js) - 密码管理 ```javascript // 监听保存密码请求 chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { if (request.action === "saveCredentials") { saveCredentials(request.hostname, request.username, request.password); sendResponse({status: "success"}); } }); // 安全保存凭证 async function saveCredentials(hostname, username, password) { // 获取当前存储的凭证 const result = await chrome.storage.local.get(['credentials']); const credentials = result.credentials || {}; // 加密密码(实际应用中应使用更强大的加密方法) const encryptedPassword = btoa(password); // 更新凭证 credentials[hostname] = { username, password: encryptedPassword, timestamp: Date.now() }; // 保存回存储 await chrome.storage.local.set({credentials}); console.log(`Credentials saved for ${hostname}`); } ``` ### 4. 创建用户界面(popup.html) ```html <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>密码管理器</title> <style> body { width: 400px; padding: 15px; font-family: Arial, sans-serif; } .header { margin-bottom: 20px; border-bottom: 1px solid #eee; padding-bottom: 10px; } .site-list { max-height: 300px; overflow-y: auto; margin-bottom: 15px; } .site-item { padding: 10px; border-bottom: 1px solid #eee; cursor: pointer; } .site-item:hover { background-color: #f5f5f5; } .actions { display: flex; justify-content: space-between; margin-top: 15px; } button { padding: 8px 15px; background-color: #4285f4; color: white; border: none; border-radius: 4px; cursor: pointer; } button:hover { background-color: #3367d6; } </style> </head> <body> <div class="header"> <h2>密码管理器</h2> </div> <div class="site-list" id="siteList"> <!-- 网站列表将动态加载 --> </div> <div class="actions"> <button id="saveCurrent">保存当前登录信息</button> <button id="settings">设置</button> </div> <script src="popup.js"></script> </body> </html> ``` ### 5. 实现弹出窗口脚本(popup.js) ```javascript document.addEventListener('DOMContentLoaded', async () => { // 获取当前活动标签页 const [tab] = await chrome.tabs.query({active: true, currentWindow: true}); const hostname = new URL(tab.url).hostname; // 加载保存的凭证 const result = await chrome.storage.local.get(['credentials']); const credentials = result.credentials || {}; // 填充网站列表 const siteList = document.getElementById('siteList'); siteList.innerHTML = ''; for (const [site, creds] of Object.entries(credentials)) { const siteItem = document.createElement('div'); siteItem.className = 'site-item'; siteItem.innerHTML = ` <strong>${site}</strong> <div>用户名: ${creds.username}</div> `; siteItem.addEventListener('click', () => { // 发送消息到内容脚本填充凭证 chrome.tabs.sendMessage(tab.id, { action: "fillCredentials", hostname: site, credentials: creds }); }); siteList.appendChild(siteItem); } // 保存当前登录信息 document.getElementById('saveCurrent').addEventListener('click', async () => { // 发送消息到内容脚本获取当前登录信息 const response = await chrome.tabs.sendMessage(tab.id, { action: "getCurrentCredentials" }); if (response && response.username && response.password) { // 发送保存请求到后台 chrome.runtime.sendMessage({ action: "saveCredentials", hostname, username: response.username, password: response.password }); alert(`已保存 ${hostname} 的登录信息`); window.close(); } else { alert("未检测到登录表单"); } }); }); ``` ## 安全注意事项 1. **密码加密**:实际应用中应使用更强大的加密方法(如Web Crypto API) 2. **权限控制**:仅请求必要的权限 3. **用户确认**:在保存密码前请求用户确认 4. **安全存储**:使用chrome.storage.local而不是localStorage 5. **自动锁定**:实现一段时间不活动后自动锁定 ## 扩展安装与测试 1. 在Chrome地址栏输入 `chrome://extensions` 2. 开启"开发者模式" 3. 点击"加载已解压的扩展程序" 4. 选择包含上述文件的文件夹 5. 访问需要登录的网站测试功能 ## 解决浏览器自动填充问题 在扩展中,我们通过以下方式解决了引用[3]中提到的问题: - 填充后手动触发`input`和`change`事件 - 添加500ms延迟后尝试提交表单 - 提供多种选择器匹配不同网站的表单结构 ## 扩展功能优化建议 1. 添加主密码保护 2. 实现跨设备同步功能 3. 添加密码生成器 4. 实现密码泄露检测 5. 添加自动提交选项设置 ## 总结 通过开发谷歌浏览器扩展实现自动填充账号密码功能,可以: 1. 解决浏览器原生自动填充的兼容性问题 2. 提供更一致的用户体验 3. 实现跨网站的密码管理 4. 添加额外的安全保护层 在开发过程中,需要特别注意用户隐私和密码安全,遵循最小权限原则,并确保用户始终对密码操作有完全控制权。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值