谷歌浏览器插件带来了很大的方便,于是就想着是不是也可以开发一个来用用。几经折腾下,开发了个CSDN快速 登陆的插件。下面简述一下开发的步骤。

1、开发工具:谷歌浏览器(我开发时用的是chrome 30.0.1599.101)、HTML/JS/CSS/JSON开发工具(UE、VS等,当然也可以用记事本)

2、开发过程

(1)新建清单文件manifest.json:该名字不可以改。下面是代码

{"manifest_version": 2,   "background": {"page": "main.html"//后台运行页,page和scrptis只能选择一个     },"browser_action":{"default_icon":"assets/images/Icon.png",//插件默认图标"default_title":"__MSG_manifest_iconTitle__",//插件标题"default_popup":"popup.html"//单击插件图标时弹出的页面},"default_locale":"en",//默认本地化语言"description":"__MSG_manifest_appDescription__",//插件描述"icons":{//显示的图标"16":"assets/images/Icon.png","128":"assets/images/Icon.png"},"name":"__MSG_manifest_appName__",//插件名字"options_page":"options.html",//插件选项页"permissions":[ "proxy", "tabs", "<all_urls>","notifications"],//申请需要的权限"version":"1.1.1",//插件版本"minimum_chrome_version":"18.0.0"//浏览器最低版本
}

其中__MSG_manifest_iconTitle__、__MSG_manifest_appDescription__、__MSG_manifest_appName__是依据系统语言的本地化配置,比如在简体中文系统和英文系统时会本地化成相应的语言,见下图

(2)新建弹出页(popup.html)

写HTML和CSS代码,排布出如上图所示的界面

<html xmlns="http://www.w3.org/1999/xhtml">
<head><link rel="stylesheet" href="assets/styles/popup.css" type="text/css"><script src="assets/libs/jquery-1.7.2.min.js" type="text/javascript"></script><script src="assets/scripts/Popup.js" type="text/javascript"></script>
</head>
<body>   <div id="set_config"><div class="header title" data-i18n-content="popup_setting">Setting</div><div class="header light"><table><tr><th><span data-i18n-content="popup_account_id">User</span></th><td><input type="text" id="setting_account_id" value="" /></td></tr><tr><th><span data-i18n-content="popup_password">Password</span></th><td><input type="password" id="setting_password" value="" /></td></tr>                </table></div><div class="header light"><table class="control"><tr><td><button class="button bold" id="setting_login" data-i18n-content="popup_setting_login">Save</button></td><td>    </td><td><button class="button bold" id="setting_cancel" data-i18n-content="popup_setting_cancel">Cancel</button></td></tr></table></div></div>
</body></html>

注意:这里面也采用了本地化配置,data-i18n-content="popup_setting"一类的写法,就是进行本地化配置,不过需要通过i18n.js来配套实现。i18n表示的是国际化。人们常把I18N作为“国际化”的简称,其来源是英文单词 internationalization的首末字符i和n。18为中间的字符数。
这里面还用到了popup.js和jquery。jquery是JS库,网上可以下载到。popup.js代码如下

/// <reference path="Config.js"/>
/// <reference path="Settings.js"/>
/// <reference path="Notify.js"/>var Popup = {};
Popup.CONTROL_IDS = {SET_CANCEL: "setting_cancel",SET_LOGIN: "setting_login",SETTING_ACCOUNT_ID: "setting_account_id",SETTING_PASSWORD: "setting_password"
};$(document).ready(function () {Popup.init();$("#" + Popup.CONTROL_IDS.SET_LOGIN).click(Popup.setLogin);$("#" + Popup.CONTROL_IDS.SET_CANCEL).click(Popup.setCancel);
});Popup.init = function () {Popup.extension = chrome.extension.getBackgroundPage();Settings = Popup.extension.Settings;//Settings in Settings.js  Config = Popup.extension.Config;//Config in Config.jsNotify = Popup.extension.Notify;I18n = Popup.extension.I18n;//I18n in I18n.js I18n.process(document);document.body.style.visibility = "visible";Popup.initUI();
}Popup.initUI = function () {$("#" + Popup.CONTROL_IDS.SETTING_ACCOUNT_ID).attr("value", Settings.getValue(Config.KEYS.ACCOUNT_ID, ''));$("#" + Popup.CONTROL_IDS.SETTING_PASSWORD).attr("value", Settings.getValue(Config.KEYS.PASSOWRD, ''));
}Popup.openPage = function () {Popup.closePopup();chrome.tabs.create({//新建标签页url: Config.URLS.LOGIN});
}Popup.openOptions = function () {Popup.closePopup();extension.openOptions();
}Popup.closePopup = function () {window.close();
}Popup.setCancel = function () {Popup.closePopup();
}Popup.setLogin = function () {Settings.setValue(Config.KEYS.ACCOUNT_ID, $("#" + Popup.CONTROL_IDS.SETTING_ACCOUNT_ID).val());Settings.setValue(Config.KEYS.PASSOWRD, $("#" + Popup.CONTROL_IDS.SETTING_PASSWORD).val());Notify.notifyText(Config.FILES.NOTIFY_IMAGE, '', 'OK');Popup.openPage();
}

说明:

1) /// <reference path="Config.js"/>是VS中为了可以像类一样点出相应的字段和方法的引用方法。

2)$(document).ready是popup.html加载完成后进行相应的操作,比如初始化按钮的点击事件等。chrome是不可以在页面中直接写内连的JS的,那样有安全隐患。

<scritp type="text/javascript">
//内连脚本
function test(){ alert("test");}
</script>

如果非要进行内连,那必须将其转换成64码,然后连到src中(直接放到scrpit中的scr中不可以,需要放到iframe中。不知道具体是什么原因。),如下面代码。

<iframe id="sandbox-frame" sandbox="allow-scripts" src="data:text/html;base64,JTNDc2NyaXB0JTIwdHlwZSUzRCUyMnRleHQvamF2YXNjcmlwdCUyMiUzRSUwQWFsZXJ0JTI4JTIyQUFBQSUyMiUyOSUzQiUwQSUzQy9zY3JpcHQlM0U="></iframe>

3)最重要的是Popup.init函数,这个函数将后台的js引用到前台(popup.js是从前台界面popup.html中引用的,所以为前台JS),以便于更好的调用。

Popup.extension = chrome.extension.getBackgroundPage()先把后台引用到前台。

Config = Popup.extension.Config是从后台将Config引用到前台来,其中Config不是Config.js的脚本名字,而是Config.js中的var Config={}。其他的引用同理。

I18n.process(document)这是进行本地化配置。

(3)后台JS

后台JS需要放到main.html中,代码如下

<html>
<head><meta charset="UTF-8" /><title></title><script src="assets/libs/jquery-1.7.2.min.js" type="text/javascript"></script><script src="assets/scripts/CSDN.js" type="text/javascript"></script><script src="assets/scripts/Settings.js" type="text/javascript"></script><script src="assets/scripts/Config.js" type="text/javascript"></script><script src="assets/scripts/I18n.js" type="text/javascript"></script><script src="assets/scripts/Notify.js" type="text/javascript"></script>
</head>
<body>
</body>
</html>

1)CSDN.js

/// <reference path="Config.js"/>
var CSDN = {};chrome.tabs.onUpdated.addListener(function (tabId, changeInfo, tab) {//添加监听事件var url = tab.url;var config = null;if (tab.status !== "complete") {//需要增加这一判断,不然会在页面加载和加载完成后分别触发return;}CSDN.login(url);
});CSDN.CONTROL_IDS = {ACCOUNT_ID: "u",PASSWORD: "p",LOGIN: "aLogin",LOGIN_IFRAME: "logfrm"
};CSDN.isLoginUrl = function (url) {if (url === Config.URLS.LOGIN) {return true;}else {return false;}
}CSDN.login = function (url) {if (!CSDN.isLoginUrl(url)) {return;}var accountID = Settings.getValue(Config.KEYS.ACCOUNT_ID, '');var password = Settings.getValue(Config.KEYS.PASSOWRD, '');var scripts = "";if (accountID === undefined || accountID === null || accountID.replace(/(^\s*)|(\s*$)/g, "").length <= 0) {return;}scripts += "var loginIFrame = document.getElementById('" + CSDN.CONTROL_IDS.LOGIN_IFRAME + "');"+ " var loginDocument=loginIFrame.contentWindow.document;"+ "loginDocument.getElementById('" + CSDN.CONTROL_IDS.ACCOUNT_ID + "').value='" + accountID + "';"+ "loginDocument.getElementById('" + CSDN.CONTROL_IDS.PASSWORD + "').value='" + password + "';"+ "loginDocument.getElementById('" + CSDN.CONTROL_IDS.LOGIN + "').click();"chrome.tabs.executeScript(null, {//嵌入JS脚本到所打开的页面中。code: scripts});
}

2)Notify.js

从浏览器中发出桌面通知,代码如下

var Notify = {};
Notify.notifyText = function (iconUrl, title, content) {//这个要触发,必须在manifest.json中添加notifications,以申请桌面通知权限var notification = window.webkitNotifications.createNotification(iconUrl, title, content);notification.show();
}

3)其他JS代码如下

Config.js

var Config = {};Config.KEYS = {ACCOUNT_ID: "accountID",   PASSOWRD: "password"
};Config.FILES = {NOTIFY_IMAGE: "assets/images/Notify.png"
};Config.URLS = {LOGIN: "https://passport.csdn.net/account/login"
};

Setting.js

var Settings = {};Settings.configCache = {};Settings.setValue = function setValue(key, value) {Settings.configCache[key] = value;var config = {};if (localStorage.config)config = JSON.parse(localStorage.config);config[key] = value;localStorage.config = JSON.stringify(config);return value;
};Settings.getValue = function getValue(key, defaultValue) {if (typeof Settings.configCache[key] != "undefined")return Settings.configCache[key];if (!localStorage.config)return defaultValue;var config = JSON.parse(localStorage.config);if (typeof config[key] == "undefined")return defaultValue;Settings.configCache[key] = config[key];return config[key];
};Settings.keyExists = function keyExists(key) {if (!localStorage.config)return false;var config = JSON.parse(localStorage.config);return (config[key] != undefined);
};Settings.setObject = function setObject(key, object) {localStorage[key] = JSON.stringify(object);return object;
};Settings.getObject = function getObject(key) {if (localStorage[key] == undefined)return undefined;return JSON.parse(localStorage[key]);
};Settings.refreshCache = function refreshCache() {Settings.configCache = {};
};

I18n.js

var I18n = {};I18n.messages = null;I18n.init = function init() {I18n.messages = I18n.readMessages();//   I18n.readMessages(function(messages) {//        I18n.messages = messages;// });
};I18n.buildMessages = function buildMessages() {var result = "\n";$("*[data-i18n-content]").each(function (i, item) {result += '"' + item.getAttribute("i18n-content") + '"' +': { "message": "' + item.innerHTML.replace(/[ \r\n\t]+/g, " ") + '" },\n';});$("*[data-i18n-values]").each(function (i, item) {$(item.getAttribute("i18n-values").split(";")).each(function (i, subItem) {var subItemParts = subItem.split(":");if (subItemParts.length == 2 && subItemParts[0].charAt(0) != ".") {result += '"' + subItemParts[1] + '"' +': { "message": "' + item.getAttribute(subItemParts[0]).replace(/[\r\n]/g, "\\n") + '" },\n';}});});return result;
};I18n.readMessages = function readMessages(callback) {var async = (callback != undefined);var data = null;var request = new XMLHttpRequest();request.open("GET", chrome.extension.getURL("_locales/en/messages.json"), async);request.onreadystatechange = function () {if (this.readyState == XMLHttpRequest.DONE) {data = this.responseText;data = JSON.parse(data.replace(/[\r\n\t]+/g, " "));if (async)callback(data);}};request.send("");return data;
};I18n.getMessage = function getMessage(messageName, substitution) {var result = chrome.i18n.getMessage(messageName, substitution);if (result == undefined || result.length == 0) {var messageObject = I18n.messages[messageName];if (messageObject != undefined) {result = messageObject.message;if (result != undefined)result = result.replace("$1", substitution);}}return result;
};I18n.process = function process(node) {return I18nTemplate.process(node);
};I18n.init();//-------------------------------------------------------/*** i18nTemplate: http://src.chromium.org/viewvc/chrome/trunk/src/chrome/browser/resources/i18n_template.js*/
var I18nTemplate = (function () {var handlers = {/*** This handler sets the textContent of the element.*/'data-i18n-content': function (element, attributeValue) {element.innerHTML/*textContent*/ = I18n.getMessage(attributeValue);},/*** This is used to set HTML attributes and DOM properties,. The syntax* is: attributename:key; .domProperty:key; .nested.dom.property:key*/'data-i18n-values': function (element, attributeValue) {var parts = attributeValue.replace(/\s/g, '').split(/;/);for (var j = 0; j < parts.length; j++) {var a = parts[j].match(/^([^:]+):(.+)$/);if (a) {var propName = a[1];var propExpr = a[2];var value = I18n.getMessage(propExpr);if (propName.charAt(0) == '.') {var path = propName.slice(1).split('.');var object = element;while (object && path.length > 1) {object = object[path.shift()];}if (object) {object[path] = value;// In case we set innerHTML (ignoring others) we need to// recursively check the contentif (path.toString() === 'innerHTML') {process(element);}}} else {element.setAttribute(propName, value);}}}}};var attributeNames = [];for (var key in handlers) {if (handlers.hasOwnProperty(key)) {attributeNames.push(key);}}var selector = '[' + attributeNames.join('],[') + ']';function process(node) {var elements = node.querySelectorAll(selector);for (var element, i = 0; element = elements[i]; i++) {for (var j = 0; j < attributeNames.length; j++) {var name = attributeNames[j];var att = element.getAttribute(name);if (att != null) {handlers[name](element, att);}}}}return {process: process};
})();

开发时参考了SwitchProxy的源码https://code.google.com/p/switchysharp/source/。

转载请注明出处http://blog.csdn.net/xxdddail/article/details/13504259

源码在此处下载http://download.csdn.net/detail/xxdddail/6469683

谷歌插件开发(实现CSDN快速登陆)相关推荐

  1. 数栈技术干货:从0到1实现谷歌插件开发探索及应用

    本文整理自:技术干货丨谷歌插件开发探索及其应用 数栈是云原生-站式数据中台PaaS,我们在github和gitee上有一个有趣的开源项目:FlinkX,记得给我们点个star!star!star! g ...

  2. sh密码登录mysql_Shell下实现免密码快速登陆MySQL数据库的方法

    背景 当我们在 Shell 下想要通过 mysql-client 登陆到 MySQL 数据库的时候,我们总是需要非常麻烦的输入一次又一次的密码. 而且,如果你的 root 密码是高度随机的话(Last ...

  3. 如何登陆网页的back office_如何使用iPhone面容ID快速登陆应用或网页

    我们总是会在手机中下载很多App,但是不一定都能够记住这些App的密码,即使就算记住了,想要使用某些应用时,不断需要输入密码也让人觉得焦虑. 好在苹果在iOS 12中改进了密码自动填充功能,搭配您设备 ...

  4. CSDN快速涨粉秘笈---涨粉速度提升30倍

           首先,必须要强调的是,这篇文章所述的CSDN快速涨粉秘笈,是合法合规的,也是CSDN官方博客专门发文推送过的,而不是所谓的违规刷粉.        你没有看错,就是如下的CSDN官方博客 ...

  5. linux终端登录qq,在deepin linux系统下qq无法快速登陆的解决方法

    如果遇到qq无法快速登陆的问题,请用下面的解决方法处理,操作系统平台是deepin linux,浏览器是google chrome.其它的linux发行版可参考,所解决的思路大致一样. 解决deepi ...

  6. IE旺旺快速登陆分析

    IE浏览器上的旺旺快速登陆功能是用AliIMSSOLogin.SSOLoginCtrl.1这个ActiveX控件实现的.javascript访问AliIMSSOLogin.SSOLoginCtrl.1 ...

  7. 163邮箱登录页面,如何快速登陆163邮箱?

    163邮箱登录页面在哪里,很久没有登录了,在哪里登陆163邮箱呢?TOM VIP邮箱分享几招长期记住登陆入口的方法,记得收藏哦! 163邮箱登录页面 网页地址比较难记,时间久了便会连同办公邮箱的固定格 ...

  8. 谷歌广告西联汇款怎么快速提取

    谷歌广告西联汇款怎么快速提取 解决方法: 1.手机下载光大银行app 2.在搜索框输入"西联汇款",点击搜出来的结果-->选择"全部->出国金融->西联 ...

  9. XX健康:移动端开发手机验证码快速登陆

    1. 需求分析 手机快速登录功能,就是通过短信验证码的方式进行登录.这种方式相对于用户名密码登录方式,用户不需要记忆自己的密码,只需要通过输入手机号并获取验证码就可以完成登录,是目前比较流行的登录方式 ...

最新文章

  1. AI:人工智能概念之机器学习ML、深度学习DL、数据挖掘、知识发现、模式识别等重要领域之间比较关系结构图之详细攻略
  2. OpenCASCADE:Foundation Classes数据类型
  3. ArrayAndString(数组和字符串)
  4. 计算机科学梦想演讲稿,关于科技演讲稿讲话稿范文三篇
  5. sql 不允许保存更改 解决办法
  6. python 端口扫描_Python实现的端口扫描功能
  7. hammerJs-v2.0.4详解
  8. 抖音上热门精选技巧 小视频更改md5
  9. 超全整理——相机标定知识汇总
  10. 益聚星荣:B站做支付,虽迟但到
  11. 麻省理工学院公开课:经典力学
  12. 出行即服务MaaS精华主题汇总(更新至20220827)
  13. C++11 auto自动类型推导
  14. win7进去提醒未能连接一个服务器,win7系统提示“未能连接一个windows服务”这个情况如何解决...
  15. 相亲app开发,解决内存循环引用的问题
  16. 【3D视觉创新应用竞赛作品系列​】基于嵌入式的室内静态场景实时重建系统
  17. opencv中waitKey()的作用
  18. ZZULIOJ:1034: 夏季促销
  19. LeetCode-241. Different Ways to Add Parentheses [C++][Java]
  20. 用友U8案例教程采购管理后台配置

热门文章

  1. arcgis使用python脚本批量裁剪影像
  2. 原生js实现播放器操作(随机播放、上/下一首、播放/暂停)
  3. 查看附件html,附件查看器
  4. python写井字棋_python实现简单井字棋游戏
  5. APP使用相机CameraX
  6. 钉钉小程序实现富文本编辑
  7. unity Assetstore 和unityhub下载的东西在哪里
  8. oracle数据库rowid是什么,oracle数据库rowid和rownum的区别以及用法-Oracle
  9. 更新weblogic部署包,清理缓存后重启不生效
  10. 四元组类,定义了四元组类的各种方法