diff --git a/source/_posts/ASP.NET Core.md b/source/_posts/ASP.NET Core.md index e9ef580..a04d322 100644 --- a/source/_posts/ASP.NET Core.md +++ b/source/_posts/ASP.NET Core.md @@ -1958,3 +1958,8 @@ string CustomSchemaIdSelector(Type modelType) return prefix + modelType.FullName.Split('`').First(); } ``` + +# 最小 API + +## 概述 + diff --git a/source/_posts/Git.md b/source/_posts/Git.md index 708d277..807a99b 100644 --- a/source/_posts/Git.md +++ b/source/_posts/Git.md @@ -71,3 +71,5 @@ Windows下 `Win + R`运行输入`control` git config --global credential.helper wincred ``` +## 储藏 (Stash) + diff --git a/source/_posts/Linux.md b/source/_posts/Linux.md index f0a44d5..a89e265 100644 --- a/source/_posts/Linux.md +++ b/source/_posts/Linux.md @@ -168,6 +168,34 @@ root:创建者所在的组 Apr 11 2018:最后一次修改时间 home:文件名或目录名 +## 查找文件 + +### find 命令 + +基本格式:find path expression + +1. 按照文件名查找 + find / -name httpd.conf # 在根目录下 查找文件httpd.conf,表示在整个硬盘查找 + find /etc -name httpd.conf # 在 /etc 目录下查找文件 httpd.conf + find /etc -name '\*srm*' # 使用通配符\*(0或者任意多个)。表示在 /etc 目录下查找文件名中含有字符串'srm'的文件 +2. 按照文件特征查找 + find / -amin -10 # 查找在系统中最后10分钟访问的文件(access time) + find / atime -2 # 查找在系统中最后48小时访问的文件 + find / -empty # 查找在系统中为空的文件或者文件夹 + find / -group cat # 查找在系统中属于 group 为 cat 的文件 + find / -mmin -5 # 查找在系统中最后5分钟里修改过的文件(modify time) + find / -mtime -1 # 查找在系统中最后24小时里修改过的文件 + find / -user fred # 查找在系统中属于fred这个用户的文件 + find / -size +10000c # 查找出大鱼10000字节的文件(c:字节,w:双字, k:KB, M:MB, G:GB) + find / -size -1000k +3. 使用混合查找方式查找文件 + 参数有:!, -and(-a), -or(-0) + find /tmp -size +10000c -and -mtime +2 # 在/tmp目录下查找大于10000字节并在最后2分钟内修改的文件 + find / -user fred -or -user george # 在根目录下查找用户是fred或者george的文本文件 + find /tmp ! -user panda #在/tmp目录中查找所有不属于panda用户的文件 + + + ## 进程管理 ps 查看前台进程 @@ -563,13 +591,26 @@ tar -xvf mysql-5.7.41-1.el7.x86_64.rpm-bundle.tar rpm -ivh mysql-community-common-5.7.41-1.el7.x86_64.rpm rpm -ivh mysql-community-libs-5.7.41-1.el7.x86_64.rpm rpm -ivh mysql-community-libs-compat-5.7.41-1.el7.x86_64.rpm +# 如果出现以下错误 +error: Failed dependencies: + libcrypto.so.10()(64bit) is needed by mysql-community-libs-compat-5.7.41-1.el7.x86_64 + libcrypto.so.10(libcrypto.so.10)(64bit) is needed by mysql-community-libs-compat-5.7.41-1.el7.x86_64 + libssl.so.10()(64bit) is needed by mysql-community-libs-compat-5.7.41-1.el7.x86_64 + libssl.so.10(libssl.so.10)(64bit) is needed by mysql-community-libs-compat-5.7.41-1.el7.x86_64 +dnf install https://repo.almalinux.org/almalinux/8/AppStream/x86_64/os/Packages/compat-openssl10-1.0.2o-4.el8_6.x86_64.rpm rpm -ivh mysql-community-devel-5.7.41-1.el7.x86_64.rpm +# 如果出现以下错误 +error: Failed dependencies: + /usr/bin/pkg-config is needed by mysql-community-devel-5.7.41-1.el7.x86_64 +dnf install openssl-devel -y rpm -ivh mysql-community-client-5.7.41-1.el7.x86_64.rpm # 如果出现以下错误 错误:依赖检测失败: libncurses.so.5()(64bit) 被 mysql-community-client-5.7.41-1.el7.x86_64 需要 libtinfo.so.5()(64bit) 被 mysql-community-client-5.7.41-1.el7.x86_64 需要 dnf install libncurses* -y +dnf install epel-release -y +dnf install ncurses-compat-libs -y # 再次执行 rpm -ivh mysql-community-client-5.7.41-1.el7.x86_64.rpm rpm -ivh mysql-community-server-5.7.41-1.el7.x86_64.rpm # 如果出现以下提示 @@ -1149,3 +1190,17 @@ sudo supervisorctl stop all sudo supervisorctl status ``` +### 程序配置 + +```conf +[program:ckadminnetcore] +command=dotnet CK.Admin.WebApi.dll --urls http://[*]:8888 +directory=/root/www/ckadminnetcore/publish +environment=ASPNETCORE_ENVIRONMENT=Production +user=root +autostart=true +autorestart=true +stderr_logfile=/var/log/ckadminnetcore/err.log +stdout_logfile=/var/log/ckadminnetcore/out.log +stopasgroup=true +``` diff --git a/source/_posts/MySQL.md b/source/_posts/MySQL.md index 081ca86..0139953 100644 --- a/source/_posts/MySQL.md +++ b/source/_posts/MySQL.md @@ -275,6 +275,7 @@ GRANT References ON database.* TO 'username'@'%'; GRANT Select ON database.* TO 'username'@'%'; GRANT Show view ON database.* TO 'username'@'%'; GRANT Update ON database.* TO 'username'@'%'; +GRANT PROCESS ON *.* TO 'username'@'%'; ``` diff --git a/source/_posts/Vue.md b/source/_posts/Vue.md index acd85d3..8424882 100644 --- a/source/_posts/Vue.md +++ b/source/_posts/Vue.md @@ -1967,3 +1967,174 @@ npm install jsencrypt --save-dev import jsencrypt from 'jsencrypt' ``` +# Chrome 插件开发 + +## 项目配置 + +```typescript +import pkg from "../package.json"; + +const manifest: chrome.runtime.Manifest = { + // 描述manifest文件的版本号,必须为3 + manifest_version: 3, + // 描述插件的名称。这个属性就是配置我们插件名称,用于显示在插件列表 + name: pkg.name, + // 描述插件的版本号。 + version: pkg.version, + // 描述插件的简要说明。 + description: pkg.description, + // 允许使用扩展的域名 + host_permissions: ["*://*/*"], + background: { + service_worker: "src/entries/background/main.ts", + }, + // 描述插件图标的大小和文件路径。 + icons: { + "16": "images/icon16.png", + "24": "images/icon24.png", + "32": "images/icon32.png", + "48": "images/icon48.png", + }, + action: { + default_popup: "index.html", + // default_icon: { + // "16": "images/icon16.png", + // "24": "images/icon24.png", + // "32": "images/icon32.png", + // "48": "images/icon48.png", + // }, + }, + options_ui: { + page: "src/entries/options/index.html", + open_in_tab: false, + }, + // activeTab: 当扩展卡选项被改变需要重新获取新的权限 + // scripting: 使用 chrome.scripting API 在不同上下文中执行脚本 + // tabs: 操作选项卡api(改变位置等) + // storage: 访问localstorage/sessionStorage权限 + // declarativeContent: 使用 chrome.declarativeContent API 根据网页内容执行操作,而无需读取网页内容的权限。 + permissions: ["activeTab", "scripting", "declarativeContent: "], + + content_security_policy: { + extension_pages: "script-src 'self'; object-src 'self';", + }, +}; + +export default manifest; + +``` + +## 内容脚本 + +需要操作dom,并且不需要一直在后台运行,只需要再打开网页的时候运行 + +使用内容脚本(`content_scripts`)的方式运行插件即可 + +内容脚本(`content_scripts`)的特性: + +- 在页面打开,或者页面加载结束,或者页面空闲的时候注入 +- 共享页面dom,也就是说可以操作页面的dom +- JS隔离的,插件中的js定义并不会影响页面的js,也不能引用页面中的js变量、函数 + +开始使用`content_scripts`: + +`content_scripts` 有多种使用方式: + +1. 静态注入。在`manifest.json`文件中声明 +2. 动态注入。`chrome.scripting.registerContentScripts` +3. 编码注入。`chrome.scripting.executeScript` + +一般使用静态注入。 + +在`manifest.ts`文件中添加一下`content_scripts`配置 + +```typescript + content_scripts: [ + // { + // matches: ["http://192.168.0.88:8080/kaoqin-server/login*"], + // js: ["src/entries/content/kaoqin-server.js"], + // run_at: "document_end", + // }, + { + //"matches": ["http://*/*", "https://*/*"], + // "" 表示匹配所有地址 + matches: [""], + // 多个JS按顺序注入 + js: ["src/entries/content/content-script.js"], + // 代码注入的时间,可选值: "document_start", "document_end", or "document_idle",最后一个表示页面空闲时,默认document_idle + run_at: "document_end", + }, + ], +``` + +`content_scripts`还有动态注入的方式,其实就是通过调用api的方法来注入,如下示例代码: + +```typescript +chrome.scripting + .registerContentScripts([{ + id: "session-script", + js: ["content.js"], + persistAcrossSessions: false, + matches: ["*://example.com/*"], + runAt: "document_start", + }]) + .then(() => console.log("registration complete")) + .catch((err) => console.warn("unexpected error", err)) +``` + +动态注入可以scripts注入的时机更可控、或者可以更新、删除content_scripts。 + +`content_scripts`属性是一个数组,也就是说我们可以配置多个脚本规则,数组的每个元素包含多个属性: + +- matches 指定此内容脚本将被注入到哪些页面。必填 +- js 要注入匹配页面的 JavaScript 文件列表。选填 +- css 要注入匹配页面的 CSS 文件列表。选填 +- run_at 指定何时应将脚本注入页面。有三种类型,`document_start`,`document_end`,`document_idle`。默认为document_idle。选填 + +## 页面通信 + +> 由于`content_scripts`是在网页中运行的,而非在扩展的上下文中,因此它们通常需要某种方式与扩展的其余部分进行通信。 扩展页面(`options_page,bakcground,popup`)和内容脚本(`content_scripts`)之间的通信通过使用消息传递进行。 任何一方都可以侦听从另一端发送的消息,并在同一通道上做出响应。消息可以包含任何有效的 JSON 对象(空值、布尔值、数字、字符串、数组或对象)。 + +![img](Vue/16e29d0dea8191b9tplv-t2oaga2asx-jj-mark3024000q75.webp) + +![img](Vue/16e29ccb69463a4dtplv-t2oaga2asx-jj-mark3024000q75.webp) + +### 发送 + +从内容脚本(`content_scripts`) 发送到 扩展页面(`options_page,bakcground,popup`),代码示例: + +```javascript +(async () => { + const response = await chrome.runtime.sendMessage({greeting: "hello"}); + console.log(response); +})(); +``` + +从扩展页面(`options_page,bakcground,popup`)发送到 内容脚本(`content_scripts`) 代码示例: + +```javascript +(async () => { + //获取当前的tab页面 + const [tab] = await chrome.tabs.query({active: true, lastFocusedWindow: true}); + const response = await chrome.tabs.sendMessage(tab.id, {greeting: "hello"}); + console.log(response); +})(); +``` + +### 接受 + +接收消息的方法都是一样的,通过`runtime.onMessage`事件侦听器来处理消息 + +```javascript +chrome.runtime.onMessage.addListener( + function(request, sender, sendResponse) { + console.log(sender.tab ? + "from a content script:" + sender.tab.url : + "from the extension"); + if (request.greeting === "hello") + //处理完消息后、通知发送方 + sendResponse({farewell: "goodbye"}); + } +); +``` + diff --git a/source/_posts/Vue/16e29ccb69463a4dtplv-t2oaga2asx-jj-mark3024000q75.webp b/source/_posts/Vue/16e29ccb69463a4dtplv-t2oaga2asx-jj-mark3024000q75.webp new file mode 100644 index 0000000..164ea33 Binary files /dev/null and b/source/_posts/Vue/16e29ccb69463a4dtplv-t2oaga2asx-jj-mark3024000q75.webp differ diff --git a/source/_posts/Vue/16e29d0dea8191b9tplv-t2oaga2asx-jj-mark3024000q75.webp b/source/_posts/Vue/16e29d0dea8191b9tplv-t2oaga2asx-jj-mark3024000q75.webp new file mode 100644 index 0000000..04a3007 Binary files /dev/null and b/source/_posts/Vue/16e29d0dea8191b9tplv-t2oaga2asx-jj-mark3024000q75.webp differ