当前位置: 首页 > news >正文

鲜花加盟网站建设建网站的客户

鲜花加盟网站建设,建网站的客户,安徽建站平台,石家庄建设公司网站好久没做浏览器插件开发了#xff0c;因为公司堡垒机#xff0c;每次登录都要输入账号密码和验证码。太浪费时间了#xff0c;就想着做一个右键菜单形式的扩展。 实现思路也很简单#xff0c;在这里做下记录#xff0c;方便下次开发参考。 一#xff0c;先来了解下chro…好久没做浏览器插件开发了因为公司堡垒机每次登录都要输入账号密码和验证码。太浪费时间了就想着做一个右键菜单形式的扩展。 实现思路也很简单在这里做下记录方便下次开发参考。 一先来了解下chrome扩展开发必备文件。 manifest.json也叫清单文件。 先简单看下配置 //需要做C#兼职 或者浏览器插件兼职的请加我QQ3388486286 {manifest_version: 2,name: 堡垒机自动化,version: 1.0,description: 右键菜单跳转到堡垒机页面并自动登录,permissions: [tabs, contextMenus,webRequest,webRequestBlocking,https://127.0.0.4/*,http://127.0.0.4/*],background: {scripts: [background.js]},content_scripts: [{matches: [https://127.0.0.4/*,http://127.0.0.4/*],js: [JS/log.js]}],web_accessible_resources: [JS/config.json],icons: {16: Images/icon.png,48: Images/icon.png,128: Images/icon.png}} 上述配置基本包含了插件开发的常用配置。现在简单介绍下每个配置的作用 1.manifest_version 也就是版本的意思你需要使用的插件版本不过现在已经是第三版了因为之前用过2开发2和3的语法有差别估本版本还是用到老版本的语法。新版本没时间去研究反正都能用。 2.name 插件名称自定义 3.version 当前插件的版本自定义 4.description 插件描述 5.permissions 权限你需要使用哪些API就需要对应的开通权限也叫注册服务吧 tabs, 该权限可以打开新的页面 contextMenus,该权限可以右键创建新的菜单 webRequest,该权限可以监听网络请求 webRequestBlocking,该权限可以监听网络请求并且修改请求 https://127.0.0.4/*,表示插件需要访问以 HTTPS 协议开头、IP 地址为 127.0.0.4 的所有页面或资源。这意味着插件将被允许在浏览器中与这些特定的 IP 地址和相关页面进行通信无论是通过 HTTP 还是 HTTPS 访问。 http://127.0.0.4/*表示插件需要访问以 HTTP 协议开头、IP 地址为 127.0.0.4 的所有页面或资源。 添加对应的地址作用这意味着插件将被允许在浏览器中与这些特定的 IP 地址和相关页面进行通信无论是通过 HTTP 还是 HTTPS 访问。background: { scripts: [background.js] }该脚本会一直运行监听。 具体含义如下 background表示指定插件的后台脚本。 scripts表示指定后台脚本文件的路径。 background.js表示插件的后台页面脚本文件名为 background.js。 通过将脚本文件名添加到 scripts 数组中你可以告诉浏览器插件在加载时要运行哪个脚本文件作为后台页面。这个后台页面脚本通常用于处理插件的核心功能、与浏览器 API 进行交互以及响应来自其他插件部分如内容脚本或浏览器操作栏的事件。7.content_scripts //content_scripts 为业务JS注入就是你要操作前端页面元素的JS 其中matches表示你JS要注入到哪些页面地址。content_scripts: [{matches: [https://127.0.0.4/*,http://127.0.0.4/*],js: [JS/log.js] //需要注入的Js文件}]8.web_accessible_resources这里面往往放些静态全局的配置文件。 9.icons图标文件。 二 、先说下background.js的思路。 1.先注册右键菜单这样你右键浏览器就可以看到自己的扩展程序了。 chrome.contextMenus.create({title:堡垒机自动化,onclick:function(){console.log(准备跳转..)//跳转指定页面chrome.tabs.create({url:https://127.0.0.4/index.php/login},(tab){console.log(跳转成功..)console.log(tab)//执行业务代码 注入JSchrome.tabs.executeScript(tab.id,{ file: JS/content_script.js})})}})其中executeScript也是注入JS的一种方式这种方式比较灵活这种注入方式也可以和页面元素进行交互。 2.跳转到指定页面后我们需要输入账号和密码这块业务逻辑就写在content_script.js中 var credentials {};// 读取配置文件并存储到全局对象 async function getConfig() {try {const response await fetch(chrome.runtime.getURL(JS/config.json));credentials await response.json();console.log(credentials); // 打印全局对象// 调用填充函数fillCredentials();} catch (error) {console.error(Error reading config file:, error);} } // 在页面上填充账号和密码 function fillCredentials() {document.querySelector(#pwd_username).value credentials.username;document.querySelector(#pwd_pwd).value credentials.password;//GetAccessToken();}这里我们调用下getConfig()方法进行配置文件读取然后赋值给全局变量存储。然后调用fillCredentials()进行账号密码赋值。 3.验证码识别并赋值登录。 我们验证码就是一个4位字母图片这块逻辑我是直接调用百度API实现的本来想着自己后端实现但是用了下第三方库要么响应时间太久了要么就是识别不准确。百度API直接帮你解决了这2个麻烦。但是要收费我只用了100次的免费体验。 现在说下具体实现思路吧本来想着直接前端发送请求识别但是浏览器有同源策略跨域了…这个最终还是要用到后端服务于是就用了后端API去做图片识别功能了。 3.1先获取验证码图片的url地址。 这里我们在background.js中添加网络监听因为图片url有固定格式很好匹配。具体代码如下 // 声明一个变量用于保存监听器 let requestListener; // 启动网络请求监听器requestListener function(details) {// 检查请求地址是否以指定的 URL 开头if (details.url.startsWith(https://127.0.0.4/captcha/)) {// 提取图片地址const imageUrl details.url;// 输出图片地址console.log(图片地址:, imageUrl);// 在这里可以进行进一步的处理sendImageURLToContentScript(imageUrl);}}chrome.webRequest.onBeforeRequest.addListener(requestListener,{ urls: [https://127.0.0.4/captcha/*] }, // 监听以指定 URL 开头的请求[blocking]); 通过 chrome.webRequest.onBeforeRequest.addListener开启网络监听当匹配到指定url开头的信息后就代表该url是图片url然后把imageUrl传给content_script.js 这里声明下 background.js是不能直接和操作的页面通信的background.js主要操作浏览器提供的API。实际操作Dom元素需要通过业务JS去操作。这里的业务JS就是content_script.js 那么background.js和content_script.js如何通信呢看代码: // 在background.js中获取到图片地址后延迟1秒发送消息给业务 JSfunction sendImageURLToContentScript(imageUrl) {chrome.tabs.query({ active: true, currentWindow: true }, function(tabs) {if (tabs.length 0) {const tabId tabs[0].id;setTimeout(function() {chrome.tabs.sendMessage(tabId, { imageUrl: imageUrl }, function(response) {// 在收到业务 JS 的响应后进行处理可选console.log(收到业务 JS 的响应:, response);});}, 500); // 延迟1秒后发送消息}});}通过 chrome.tabs.sendMessage 发送消息。 // 业务 JS 接收消息并进行处理 chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {// 接收到来自 background.js 的消息if (request.imageUrl) {const imageUrl request.imageUrl;// 在这里进行业务逻辑处理使用获取到的图片地址console.log(收到来自 background.js 的图片地址:, imageUrl);GetCode(imageUrl);//GetBase64(imageUrl);// 可以通过 sendResponse 向 background.js 发送响应消息可选sendResponse({ message: 已收到图片地址 });}});通过chrome.runtime.onMessage.addListener接收消息 这样就实现了background.js和content_script.js的通信。 至于为什么要延迟500毫秒再发送是因为我们点击右键后content_script.js才注入到页面而再这时候background.js已经再运行了。所有延迟会再发送消息这样可以避免content_script.js那边接收不到消息。 3.2业务JS发送imageUrl给后端api进行图像验证码识别 function GetCode(imageUrl){fetch(credentials.getcode_url, {method: POST,headers: {Content-Type: application/json},body: JSON.stringify(imageUrl)}).then(response response.text()).then(result {let data JSON.parse(result);// 获取 words_result 字段的值 let wordsResult data.words_result;// 获取数组中第一个元素的 words 字段的值let words wordsResult[0].words;console.log(words); // 输出: code//赋值codedocument.querySelector(#pwd_captcha).value words;//点击登录document.querySelector(#sign-box form.form-vertical.login-content.active div.submit-row button).click();}).catch(error {console.error(请求出错:, error);});} 好了这样就实现了验证码识别然后赋值登录操作呢。 三、给出所有相关代码 config.json {username: username,password: password,client_id:FrktGAjFVjGv9SSA6S3,client_secret:IFL6FbU6tuFrPoCjaYnvvRrCGd,token_url:https://aip.baidubce.com/oauth/2.0/token,getcode_url:http://localhost:5270/api/CodeIdentity }background.js // 声明一个变量用于保存监听器 let requestListener; // 启动网络请求监听器requestListener function(details) {// 检查请求地址是否以指定的 URL 开头if (details.url.startsWith(https://127.0.0.4/captcha/)) {// 提取图片地址const imageUrl details.url;// 输出图片地址console.log(图片地址:, imageUrl);// 在这里可以进行进一步的处理sendImageURLToContentScript(imageUrl);}}chrome.webRequest.onBeforeRequest.addListener(requestListener,{ urls: [https://127.0.0.4/captcha/*] }, // 监听以指定 URL 开头的请求[blocking]);// 在background.js中获取到图片地址后延迟1秒发送消息给业务 JSfunction sendImageURLToContentScript(imageUrl) {chrome.tabs.query({ active: true, currentWindow: true }, function(tabs) {if (tabs.length 0) {const tabId tabs[0].id;setTimeout(function() {chrome.tabs.sendMessage(tabId, { imageUrl: imageUrl }, function(response) {// 在收到业务 JS 的响应后进行处理可选console.log(收到业务 JS 的响应:, response);});}, 500); // 延迟1秒后发送消息}});}chrome.contextMenus.create({title:堡垒机自动化,onclick:function(){console.log(准备跳转..)//跳转指定页面chrome.tabs.create({url:https://127.0.0.4/index.php/login},(tab){console.log(跳转成功..)console.log(tab)//执行业务代码 注入JSchrome.tabs.executeScript(tab.id,{ file: JS/content_script.js})})}})// // 启动网络请求监听器 // chrome.webRequest.onBeforeRequest.addListener( // function(details) { // // 检查请求地址是否以指定的 URL 开头 // if (details.url.startsWith(https://127.0.0.4/captcha/)) { // // 提取图片地址 // const imageUrl details.url;// // 输出图片地址 // console.log(图片地址:, imageUrl);// // 在这里可以进行进一步的处理 // sendImageURLToContentScript(imageUrl); // } // }, // { urls: [https://127.0.0.4/captcha/*] }, // 监听以指定 URL 开头的请求 // [blocking] // );// 在background.js中获取到图片地址后延迟1秒发送消息给业务 JS // function sendImageURLToContentScript(imageUrl) { // chrome.tabs.query({ active: true, currentWindow: true }, function(tabs) { // if (tabs.length 0) { // const tabId tabs[0].id;// setTimeout(function() { // chrome.tabs.sendMessage(tabId, { imageUrl: imageUrl }, function(response) { // // 在收到业务 JS 的响应后进行处理可选 // console.log(收到业务 JS 的响应:, response); // // 移除监听器 // chrome.webRequest.onBeforeRequest.removeListener(requestListener); // }); // }, 100); // 延迟1秒后发送消息 // } // }); // }// 开始监听网络请求 //startRequestListener(); content_script.js // 业务 JS 接收消息并进行处理 chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {// 接收到来自 background.js 的消息if (request.imageUrl) {const imageUrl request.imageUrl;// 在这里进行业务逻辑处理使用获取到的图片地址console.log(收到来自 background.js 的图片地址:, imageUrl);GetCode(imageUrl);//GetBase64(imageUrl);// 可以通过 sendResponse 向 background.js 发送响应消息可选sendResponse({ message: 已收到图片地址 });}});var credentials {};// 读取配置文件并存储到全局对象 async function getConfig() {try {const response await fetch(chrome.runtime.getURL(JS/config.json));credentials await response.json();console.log(credentials); // 打印全局对象// 调用填充函数fillCredentials();} catch (error) {console.error(Error reading config file:, error);} } // 在页面上填充账号和密码 function fillCredentials() {document.querySelector(#pwd_username).value credentials.username;document.querySelector(#pwd_pwd).value credentials.password;//GetAccessToken();}/*** 使用 AKSK 生成鉴权签名Access Token* returns 鉴权签名信息Access Token*/ // function GetAccessToken() { // const url credentials.token_url; // const data { // grant_type: client_credentials, // client_id: credentials.client_id, // client_secret: credentials.client_secret // };// const requestOptions { // method: POST, // mode: cors, // headers: { Content-Type: application/json }, // body: JSON.stringify(data) // };// return fetch(url, requestOptions) // .then(response { // if (!response.ok) { // throw new Error(Network response was not ok); // } // return response.json(); // }) // .then(data { // console.log(data); // console.log(data.access_token); // return data.access_token; // }) // .catch(error { // console.error(error); // }); // }function GetCode(imageUrl){fetch(credentials.getcode_url, {method: POST,headers: {Content-Type: application/json},body: JSON.stringify(imageUrl)}).then(response response.text()).then(result {let data JSON.parse(result);// 获取 words_result 字段的值 let wordsResult data.words_result;// 获取数组中第一个元素的 words 字段的值let words wordsResult[0].words;console.log(words); // 输出: code//赋值codedocument.querySelector(#pwd_captcha).value words;//点击登录// document.querySelector(#sign-box form.form-vertical.login-content.active div.submit-row button).click();}).catch(error {console.error(请求出错:, error);});}//图片转base64 // function getFileContentAsBase64(path) { // return new Promise((resolve, reject) { // fetch(path) // .then(response response.arrayBuffer()) // .then(buffer { // const bytes new Uint8Array(buffer); // let binary ; // for (let i 0; i bytes.byteLength; i) { // binary String.fromCharCode(bytes[i]); // } // const base64 btoa(binary); // resolve(base64); // }) // .catch(error reject(error)); // }); // }// function GetBase64(captchaUrl) // { // // 使用fetch函数获取验证码图片的二进制数据 // fetch(captchaUrl) // .then(response response.blob()) // .then(blob { // // 创建一个FileReader对象来读取blob数据 // const reader new FileReader(); // reader.onloadend function() { // // 读取完成后将二进制数据转换为Base64编码 // const base64 reader.result.split(,)[1];// // 调用getFileContentAsBase64方法进行后续处理 // getFileContentAsBase64(base64) // .then(result { // console.log(base64:,result); // }) // .catch(error { // console.error(error); // }); // }; // reader.readAsDataURL(blob); // }) // .catch(error { // console.error(error); // });// }//识别验证码// 获取配置并存储到全局对象 getConfig(); 后端代码 using CodeIdentify.Servers;var builder WebApplication.CreateBuilder(args);// Add services to the container.builder.Services.AddControllers(); // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); builder.Services.AddScopedIBaiDuCodeIdentity, BaiDuCodeIdentityRepostoty(); builder.Services.AddCors(options {options.AddPolicy(AllowAll, builder {builder.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader();}); });var app builder.Build();app.UseCors(AllowAll); // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment()) {app.UseSwagger();app.UseSwaggerUI(); }app.UseAuthorization();app.MapControllers();app.Run(); namespace CodeIdentify.Servers {public interface IBaiDuCodeIdentity{Taskstring GetAccessTokenAsync();Taskstring GetCodeAsync(string base64);Task DownloadImageAsync(string url , string saveDirectory);string GetFileContentAsBase64(string path);void DeleteImage(string path);} } using Microsoft.OpenApi.Models; using Newtonsoft.Json; using RestSharp; using System.Net;namespace CodeIdentify.Servers {public class BaiDuCodeIdentityRepostoty : IBaiDuCodeIdentity{public void DeleteImage(string path){try{// 获取指定文件夹中的所有图片文件string[] imageFiles Directory.GetFiles(path, *.jpg);foreach (string file in imageFiles){// 删除文件File.Delete(file);Console.WriteLine($已删除文件: {file});}Console.WriteLine(所有图片文件已删除。);}catch (Exception ex){throw new Exception(ex.Message);Console.WriteLine($删除图片文件时出错{ex.Message});}}public async Task DownloadImageAsync(string imageUrl, string saveDirectory){// 创建自定义的 HttpClientHandler并禁用证书验证var handler new HttpClientHandler(){ServerCertificateCustomValidationCallback (sender, cert, chain, sslPolicyErrors) true};// 创建 HttpClient 实例并使用自定义的 HttpClientHandlerusing (HttpClient httpClient new HttpClient(handler)){try{// 发送 GET 请求并获取响应消息HttpResponseMessage response await httpClient.GetAsync(imageUrl);response.EnsureSuccessStatusCode();// 从响应消息中获取图片内容byte[] imageBytes await response.Content.ReadAsByteArrayAsync();// 创建文件保存路径Directory.CreateDirectory(saveDirectory);string savePath Path.Combine(saveDirectory, image.jpg); // 要保存的文件名// 将图片内容保存到本地文件File.WriteAllBytes(savePath, imageBytes);Console.WriteLine(图片下载完成。);}catch (Exception ex){throw new Exception($图片下载失败{ex.Message});Console.WriteLine($图片下载失败{ex.Message});}}}public async Taskstring GetAccessTokenAsync(){try{var client new RestClient($https://aip.baidubce.com/oauth/2.0/token?grant_typeclient_credentialsclient_idFrktGAjFVjSSA6S3Tcs0fclient_secretIFL6FbU6rPoCjaSiKjMLYnvvRrCGd);var request new RestRequest(String.Empty, Method.Post);request.AddHeader(Content-Type, application/json);request.AddHeader(Accept, application/json);var body ;request.AddParameter(application/json, body, ParameterType.RequestBody);var response await client.ExecuteAsync(request);var result JsonConvert.DeserializeObjectdynamic(response.Content??);Console.WriteLine(result?.access_token.ToString());return result?.access_token.ToString()??;}catch (Exception e){throw new Exception($可能次数用完了{e.Message});}}public async Taskstring GetCodeAsync(string base64){var token await GetAccessTokenAsync();var client new RestClient($https://aip.baidubce.com/rest/2.0/ocr/v1/accurate_basic?access_token{token});var request new RestRequest(String.Empty, Method.Post);request.AddHeader(Content-Type, application/x-www-form-urlencoded);request.AddHeader(Accept, application/json);// image 可以通过 GetFileBase64Content(C:\fakepath\captcha.png) 方法获取request.AddParameter(image, base64);var response await client.ExecuteAsync(request);Console.WriteLine(response.Content);return response.Content??;}public string GetFileContentAsBase64(string path){using (FileStream filestream new FileStream(path, FileMode.Open)){byte[] arr new byte[filestream.Length];filestream.Read(arr, 0, (int)filestream.Length);string base64 Convert.ToBase64String(arr);return base64;}}} } using CodeIdentify.Servers; using Microsoft.AspNetCore.Mvc;namespace CodeIdentify.Controllers {[Route(api/[controller])][ApiController]public class CodeIdentityController : ControllerBase{private readonly IBaiDuCodeIdentity _baiDuCodeIdentity;public CodeIdentityController(IBaiDuCodeIdentity baiDuCodeIdentity) {_baiDuCodeIdentity baiDuCodeIdentity;}[HttpPost]public async TaskIActionResult GetCode([FromBody] string url) {string path Images\\image.jpg;string deletepath Images;await _baiDuCodeIdentity.DownloadImageAsync(url, Images);string code await _baiDuCodeIdentity.GetCodeAsync(_baiDuCodeIdentity.GetFileContentAsBase64(path));if(string.IsNullOrWhiteSpace(code)) return BadRequest(空字符串识别有误);_baiDuCodeIdentity.DeleteImage(deletepath);return Ok(code);} } }
http://www.yutouwan.com/news/421847/

相关文章:

  • net域名做企业网站怎么样链接网址怎么做
  • 网站友情链接的作用如何做网络推广赚钱
  • 最新网站信息成都seo优化外包公司
  • 建设银行网站关闭闪付h5网站建设 北京
  • 二手车网站模版售价荥阳网站建设多少钱
  • 专业团队值得信赖西安网站seo收费
  • 青海建设银行的官方网站wordpress添加script
  • 个人网站 百度推广河南省建设厅网站 吴浩
  • 网站的宽度浅析个人网站的设计论文
  • 东阳做网站中国最大的软件公司排名
  • 网站等保需要几年一做农业科技工作服务站建站模板
  • 瘦身网站开发目的做网站建设工资多少
  • 深圳做分销商城网站服务器建网站
  • 做网站如何宣传WordPress给编辑器
  • 郑州建设企业网站找哪个公司我常用的网站有哪些类型有哪些类型有哪些
  • 高校网站模板赤峰网站制作公司
  • 南京网站优化公司泰安人才网官网登录
  • 什么做网站赚钱工装公司联系方式
  • 网站建设是专业南昌购物网站开发
  • 学百度推广培训石家庄网站建设优化
  • 铁道部建设监理协会网站做网站的网页设计用cdr吗
  • 郓城如何做网站seo嘉兴城乡建设局门户网站
  • 网站建设详细方案模板网站 做 app开发工具
  • 燕郊做网站找谁四川公众项目咨询管理有限公司
  • 域名解析映射到网站空间怎么做类似返利网的网站建设
  • 创建网站的优势网站的构成
  • 外贸是什么意思seo排名培训公司
  • 做推广要知道的网站百度平台商家
  • 做相亲网站的红娘累吗做网站要多少钱一个
  • 电子商务网站建设流程是什么三明建设局网站