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

建设网站用什么语言比较好微信公众号开店流程

建设网站用什么语言比较好,微信公众号开店流程,推广游戏的平台,软件界面设计工具有哪些软件说在前面 平时大家都是怎么管理自己的浏览器书签数据的呢#xff1f;有没有过公司和家里的电脑浏览器书签不同步的情况#xff1f;有没有过电脑突然坏了但书签数据没有导出#xff0c;导致书签数据丢失了#xff1f;解决这些问题的方法有很多#xff0c;我选择自己写个chr…说在前面 平时大家都是怎么管理自己的浏览器书签数据的呢有没有过公司和家里的电脑浏览器书签不同步的情况有没有过电脑突然坏了但书签数据没有导出导致书签数据丢失了解决这些问题的方法有很多我选择自己写个chrome插件来做书签同步。 实现方案 通过 gitee 来做存取 建一个私有仓库来保存自己的书签目录信息需要同步的时候再获取 gitee 仓库的书签目录到本地。这样不用自己写服务端对数据进行存储减少了很多不必要的开发工作。 实现步骤 一、准备工作 1、新建 gitee 仓库 直接在gitee上新建仓库即可。 我们不想要书签信息公开所以选择勾选上私有 创建完的初始仓库是这样的 我们再新增一个目录用于存放和书签相关的文件 在该目录下新增一个文件用于保存书签导出的数据 二、插件编写 完成前面的准备工作新建完 gitee 仓库之后我们便可以正式开始进行插件的编写了。 1、插件模板 安装依赖jyeontu npm i -g jyeontu获取模板 jyeontu create生成模板 根据提示输入相关信息即可 2、giteeAPI 我们可以通过 giteeAPI 来对 gitee 仓库进行操作下面是 giteeAPI 的操作文档 https://gitee.com/api/v5/swagger#/getV5ReposOwnerRepoStargazers?exno 获取gitee指定文件的内容 我们可以通过下面代码来获取到gitee指定仓库指定文件的内容 async function fetchFileContent(apiUrl, accessToken) {const response await fetch(apiUrl, {headers: {Authorization: token accessToken,},});const fileData await response.json();return fileData.content; }export async function getFile(gitInfo) {const accessToken gitInfo.token;const apiUrl https://gitee.com/api/v5/repos/ gitInfo.owner / gitInfo.repo /contents/ gitInfo.filePath;const fileContent await fetchFileContent(apiUrl, accessToken);const decodedContent atob(fileContent); // 解码Base64编码的文件内容const decoder new TextDecoder();const decodedData decoder.decode(new Uint8Array([...decodedContent].map((char) char.charCodeAt(0))));return JSON.parse(decodedData); }修改指定文件的内容数据 我们需要先获取到文件拿到文件的sha值后面通过sha来对文件进行编辑操作。 btoa函数只能处理Latin1字符范围内的字符串对超出Latin1字符范围的字符串进行Base64编码我们需要进行以下操作使用TextEncoder对象来将字符串转换为字节数组然后再进行Base64编码。 async function fetchFileContent(apiUrl, accessToken) {const response await fetch(apiUrl, {headers: {Authorization: token accessToken,},});const fileData await response.json();return fileData.content; } async function getDecodedContent(content) {const decodedContent atob(content); // 解码Base64编码的文件内容const decoder new TextDecoder();const decodedData decoder.decode(new Uint8Array([...decodedContent].map((char) char.charCodeAt(0))));return JSON.parse(decodedData); } async function putFileContent(apiUrl, accessToken, encodedContent, sha) {const commitData {access_token: accessToken,content: encodedContent,message: Modified file,sha: sha,};const putResponse await fetch(apiUrl, {method: PUT,headers: {Content-Type: application/json,Authorization: token accessToken,},body: JSON.stringify(commitData),});if (putResponse.ok) {console.log(File modified successfully.);} else {console.error(Failed to modify file.);} } export async function modifyFile(gitInfo, modifiedContent) {const accessToken gitInfo.token;const apiUrl https://gitee.com/api/v5/repos/ gitInfo.owner / gitInfo.repo /contents/ gitInfo.filePath;try {const fileContent await fetchFileContent(apiUrl, accessToken);const content await getDecodedContent(fileContent);modifiedContent mergeBookmarks(content, modifiedContent);modifiedContent JSON.stringify(modifiedContent);const encoder new TextEncoder();const data encoder.encode(modifiedContent);const encodedContent btoa(String.fromCharCode.apply(null, new Uint8Array(data)));await putFileContent(apiUrl, accessToken, encodedContent, fileContent.sha);} catch (error) {console.error(An error occurred:, error);} }3、indexDb存取 我们不希望每次打开都需要去重新填写gitee仓库的相关信息所以这里我们使用indexDb来对gitee仓库的相关信息做一个保存。 export class IndexedDB {constructor(databaseName, storeName) {this.databaseName databaseName;this.storeName storeName;this.db null;}open() {return new Promise((resolve, reject) {const request window.indexedDB.open(this.databaseName);request.onerror () {reject(new Error(Failed to open database));};request.onsuccess () {this.db request.result;resolve();};request.onupgradeneeded (event) {this.db event.target.result;if (!this.db.objectStoreNames.contains(this.storeName)) {this.db.createObjectStore(this.storeName, {keyPath: id,autoIncrement: true,});}};});}createDatabase() {return new Promise((resolve, reject) {const request window.indexedDB.open(this.databaseName);request.onerror () {reject(new Error(Failed to create database));};request.onsuccess () {this.db request.result;this.db.close();resolve();};request.onupgradeneeded (event) {this.db event.target.result;if (!this.db.objectStoreNames.contains(this.storeName)) {this.db.createObjectStore(this.storeName, {keyPath: id,autoIncrement: true,});}this.db.close();resolve();};});}close() {if (this.db) {this.db.close();this.db null;}}add(data) {return new Promise((resolve, reject) {const transaction this.db.transaction(this.storeName, readwrite);const objectStore transaction.objectStore(this.storeName);const request objectStore.add(data);request.onsuccess () {resolve(request.result);};request.onerror () {reject(new Error(Failed to add data));};});}getAll() {return new Promise((resolve, reject) {const transaction this.db.transaction(this.storeName, readonly);const objectStore transaction.objectStore(this.storeName);const request objectStore.getAll();request.onsuccess () {resolve(request.result);};request.onerror () {reject(new Error(Failed to get data));};});}getById(id) {return new Promise((resolve, reject) {const transaction this.db.transaction(this.storeName, readonly);const objectStore transaction.objectStore(this.storeName);const request objectStore.get(id);request.onsuccess () {resolve(request.result);};request.onerror () {reject(new Error(Failed to get data));};});}delete(id) {return new Promise((resolve, reject) {const transaction this.db.transaction(this.storeName, readwrite);const objectStore transaction.objectStore(this.storeName);const request objectStore.delete(id);request.onsuccess () {resolve();};request.onerror () {reject(new Error(Failed to delete data));};});}update(id, newData) {return new Promise((resolve, reject) {const transaction this.db.transaction(this.storeName, readwrite);const objectStore transaction.objectStore(this.storeName);const getRequest objectStore.get(id);getRequest.onsuccess () {const oldData getRequest.result;if (!oldData) {const addRequest objectStore.add({ ...newData, id });addRequest.onsuccess () {resolve({ ...newData, id });};addRequest.onerror () {reject(new Error(Failed to add data));};} else {const mergedData { ...oldData, ...newData };const putRequest objectStore.put(mergedData);putRequest.onsuccess () {resolve(mergedData);};putRequest.onerror () {reject(new Error(Failed to update data));};}};getRequest.onerror () {reject(new Error(Failed to get data));};});} }4、书签存取 获取chrome书签 要获取 Chrome 浏览器的书签目录我们可以使用 Chrome 浏览器提供的 API——chrome.bookmarks。下面是一个示例代码演示如何使用chrome.bookmarks API 获取 Chrome 浏览器的书签目录 export const getBookmarks () {return new Promise((resolve) {chrome.bookmarks.getTree(function (bookmarkTreeNodes) {resolve(bookmarkTreeNodes);});}); };在上述代码中我们首先使用chrome.bookmarks.getTree()方法获取 Chrome 浏览器的书签目录树。 请注意要使用chrome.bookmarks API你需要在你的 Chrome 插件中声明bookmarks权限。具体来说在插件清单文件manifest.json中添加以下内容 {manifest_version: 2,name: 你的插件名称,version: 1.0,permissions: [bookmarks],background: {scripts: [bg.js]} }在上述代码中我们在permissions字段中声明了bookmarks权限以便我们可以使用chrome.bookmarks API。同时在background字段中指定了一个后台脚本bg.js以便我们在后台执行上述代码。 删除chrome浏览器书签 导入书签前我们需要先清除一下当前浏览器的书签通过chrome.bookmarks.removeTree可以删除书签节点。 export function removeBookmarks(bookmarkTreeNodes) {// 遍历书签树删除所有的书签function traverseBookmarks(bookmarkNodes) {for (const node of bookmarkNodes) {if (node.children) {traverseBookmarks(node.children);}// 删除书签节点chrome.bookmarks.removeTree(node.id);}}traverseBookmarks(bookmarkTreeNodes); }导入书签 使用chrome.bookmarks.create来新建书签。 export function importBookmarks(bookmarkTreeNodes) {// 遍历书签树function traverseBookmarks(bookmarkNodes, parentId) {for (const node of bookmarkNodes) {// 如果节点是文件夹if (node.children) {// 创建一个新的文件夹节点chrome.bookmarks.create({parentId: parentId,title: node.title,},function (newFolderNode) {// 递归遍历子节点traverseBookmarks(node.children, newFolderNode.id);});}// 如果节点是书签else {// 创建一个新的书签节点chrome.bookmarks.create({parentId: parentId,title: node.title,url: node.url,});}}}// 从根节点开始遍历书签树traverseBookmarks(bookmarkTreeNodes[0].children, 1); }插件使用 1、插件下载 直接到gitee上下载源码即可 源码地址https://gitee.com/zheng_yongtao/chrome-plug-in.git 2、导入插件 书签同步插件的目录如下 下载完后打开浏览器扩展程序管理页面chrome://extensions/选择加载已解压的扩展程序 选择插件目录导入即可 导入成功后就可以看到下面这个插件了 可以勾选上下面这个勾选后插件就会显示在导航栏上 3、补充gitee仓库信息数据 导入插件后我们点击导航栏的插件图标可以看到这样一个面板其中有四个数据需要我们填写 获取 token 进入到giteeAPI文档进行授权获取到返回填写即可具体步骤如下 仓库所属空间地址(owner) 就是个人主页的一个空间地址如下图 仓库路径(repo) 前面新建仓库的路径仓库名如下图 书签文件路径(filePath) 新建用于保存书签数据的文件想保存多份不同的数据的话可以多件几个不同的文件分别进行存储同步的时候选择对应的目录即可如下图 将对应信息填写上之后我们就可以开始进行同步操作了 4、同步方式 1覆盖保存 使用当前浏览器书签数据覆盖保存到gitee仓库中。 2合并保存 将当前浏览器书签数据与gitee仓库中的书签数据合并好再进行保存。 3覆盖获取 使用gitee仓库中的书签数据覆盖掉本地的书签数据。 4合并获取 将gitee仓库中的书签数据和本地的书签数据合并后再覆盖掉本地的书签数据。 5合并规则 同一层级并且同名的目录我们会将其子节点合并到同一目录下同一层级下我们会根据 书签名 书签url 对该层级的书签进行去重。 源码 1、gitee gitee 地址https://gitee.com/zheng_yongtao/chrome-plug-in/tree/master/chrome-bookmarks-manage 2、公众号 关注公众号『前端也能这么有趣』发送 chrome插件即可获取源码。 说在后面 这里是 JYeontu现在是一名前端工程师有空会刷刷算法题平时喜欢打羽毛球 平时也喜欢写些东西既为自己记录 也希望可以对大家有那么一丢丢的帮助写的不好望多多谅解 写错的地方望指出定会认真改进 偶尔也会在自己的公众号『前端也能这么有趣』发一些比较有趣的文章有兴趣的也可以关注下。在此谢谢大家的支持我们下文再见 。
http://www.hkea.cn/news/14323137/

相关文章:

  • 县城房地产网站可以做吗邯郸oa办公系统
  • 网站 建设开发合同国外的网站叫什么
  • flash网站大全有数据库的网站
  • 网站建设的优势与不足网站建设网站制作提供服务
  • 黄山市住房城乡建设厅网站响应式网站建设模板
  • 公司建设网站的服务费新开服网页游戏一览表
  • 下载网站专用空间一般网站建设电话
  • 化妆品网站开发可行性wordpress 文章字数
  • 网站建设备案审核要多久wordpress主题汉化版免费下载
  • 看网站有没有做404网站建设行业好做吗
  • 浦项建设中国有限公司网站在线制作图片影集
  • 沙田网站仿做展厅设计规划
  • 网站建设与管理基础网络服务提供者不得在什么时间
  • 聚民网网站建设wordpress首页只显示文章摘要
  • 可以和朋友合资做网站吗上虞市建设风机厂网站
  • xml天气预报网站怎么做网站统计系统
  • 怎么自己在电脑上做网站电子工程有限公司
  • 网站备案更改吗wordpress写 a href
  • 江阴安泰物流有限公司网站谁做的网页制作素材怎么分类
  • 成品网站建设价格app网站开发价格
  • 不会做网站现代化专业群建设网站
  • 陕西省住房与城乡建设部网站网站开发的几种语言
  • 万和城网站3免费网站建站
  • 泰州企业自助建站系统做网站公司能赚钱吗
  • 口碑好的坪山网站建设做网站的的价格
  • 做网站插背景图片如何变大wordpress登入页面
  • 网站注册需要什么网站框架怎么做
  • 邢台网站设计厂家发帖网站百度收率高的
  • 北京公司建网站要多少费用信阳网站推广公司
  • 深圳网站建设推广建设一个网站app需要多少钱