跳到主要内容

批量 clone GitHub 仓库

· 阅读需 1 分钟
素明诚
Full stack development

获取仓库列表,保存在当前目录下

curl https://api.github.com/users/替换为你的用户名/repos?per_page=100 > repos.json

编写 python 脚本

import json
import subprocess

# 加载仓库列表
with open('repos.json', 'r', encoding='utf-8') as file:
repos = json.load(file)

# 遍历每个仓库
for repo in repos:
# 获取仓库的克隆URL
clone_url = repo['clone_url']
# 执行克隆操作
print(f"Cloning {clone_url}...")
subprocess.run(['git', 'clone', clone_url])

python http://xx.py 运行这个脚本,clone 所有仓库

Web3 常见术语

· 阅读需 3 分钟
素明诚
Full stack development
特征Web1 (静态网页)Web2 (社交网)Web3 (去中心化网)
主导理念信息共享用户生成内容和互动去中心化、用户主权
技术基础HTML、CSSAJAX、HTML5、云计算区块链、智能合约、加密技术
数据控制网站拥有者平台拥有者(如 Facebook、Google)用户本人
主要应用静态网页社交媒体、博客、电商去中心化应用(DApps)、去中心化金融(DeFi)、NFT
用户角色内容消费者内容创作者与消费者经济参与者、治理参与者
内容验证网站管理员平台算法共识机制
交易方式传统在线支付传统在线支付 + 广告模型加密货币、令牌经济
开发模式封闭源代码开放 API(部分封闭源代码)开源和透明
Web3 组成部分描述
去中心化金融(DeFi)利用区块链技术创建的金融系统,无需传统金融中介(如银行、保险公司)即可进行借贷、交易、投资等。
去中心化自治组织(DAO)基于智能合约的组织形式,成员通过代币持有比例共同决策组织的运营事务,无需中心化管理层。
去中心化应用(DApps)运行在区块链上的应用程序,不受单一控制且抵抗审查。用户直接与 DApps 交互,数据和操作记录在区块链上。
非同质化代币(NFTs)代表独一无二的资产(如艺术品、收藏品)的加密代币,每个 NFT 都有独特的识别码和元数据区分于其他代币。
智能合约存储在区块链上的程序,自动执行、控制或记录合约条款的实现。
加密货币通过密码学保障安全的数字或虚拟货币,充当去中心化网络的交易媒介。
区块链一种分布式账本技术,数据以块链形式存储,确保数据的不可篡改性和透明性。
分布式账本技术(DLT)记录交易或资产的分布式数据库,区块链是 DLT 的一种。
互操作性不同区块链网络之间能够交换和利用信息的能力。
元宇宙(Metaverse)一个虚拟现实空间,用户可以通过 3D 化身与其他人交互、体验虚拟世界中的活动和交易。
Web3 存储解决方案去中心化的文件存储协议,如 IPFS(星际文件系统),提供分布式网络上的文件存储和访问。
身份验证和隐私保护利用区块链技术,用户可以控制自己的身份信息和隐私数据,无需依赖第三方。
链上治理在区块链协议内实施的治理机制,允许代币持有者投票决定网络的变更和升级。

后续还会继续更新

为什么是 CICD

· 阅读需 2 分钟
素明诚
Full stack development

持续集成(Continuous Integration, CI)

持续集成是一种软件开发实践,开发团队成员经常(一天中可能多次)将代码集成到共享仓库中。每次代码提交时,会自动运行构建和测试,以尽早发现并解决集成错误,提高软件质量,减少发布时的问题。CI 的关键在于自动化测试,确保代码的新更改不会破坏现有功能。

持续部署(Continuous Deployment)和持续交付(Continuous Delivery)

  • 持续交付(CD) 是持续集成的下一步,确保你可以快速、安全地将新更改部署到生产环境。在持续交付模式下,每个通过所有测试阶段的构建版本都可以被部署到生产环境,但是,最终的部署步骤可能需要手动触发。
  • 持续部署(也是 CD) 是持续交付的进一步实践,其中部署过程完全自动化,不需要人工干预。这意味着每次提交通过所有的测试后,自动无缝地部署到生产环境。这要求有高度的测试覆盖率和对生产环境的信心。

CI 和 CD 的关系

  • CI 是基础:持续集成是实现持续交付和持续部署的基础。没有有效的 CI 过程,持续交付或持续部署都难以实现。
  • 流程的延伸:可以将持续交付视为持续集成的自然延伸,而持续部署则是持续交付的进一步延伸。它们共同构成了从代码提交到生产部署的自动化流程。

CD/CD 的出现就是为了让你更早的发现系统问题

npm 命令常用简写

· 阅读需 1 分钟
素明诚
Full stack development

安装依赖项(在项目目录中)

  • 完整: npm install
  • 简写: npm i

全局安装包:

  • 完整: npm install <package> --global
  • 简写: npm i <package> -g

安装并保存到项目的依赖项(现在默认行为)

  • 完整: npm install <package>
  • 简写: npm i <package>

安装并保存到项目的开发依赖项

  • 完整: npm install <package> --save-dev
  • 简写: npm i <package> -D

运行脚本

  • 完整: npm run <script-name>
  • (没有简写)

列出已安装的包

  • 完整: npm list
  • 简写: npm ls

列出全局安装的包

  • 完整: npm list --global
  • 简写: npm ls -g

查看已安装包的版本

  • 完整: npm list <package>
  • 简写: npm ls <package>

查看远程包的最新版本

  • 完整: npm view <package> version
  • 简写: npm v <package>

卸载包

  • 完整: npm uninstall <package>
  • 简写: npm un <package>npm rm <package>

发布包

  • 完整: npm publish
  • (没有简写)

登录到 npm

  • 完整: npm login
  • (没有简写)

退出 npm

  • 完整: npm logout
  • (没有简写)

初始化新的 npm 项目

  • 完整: npm init
  • 简写 (用于快速设置): npm init -y

Nginx 配置中 root 和 alias 指令的区别

· 阅读需 4 分钟
素明诚
Full stack development

两种指令的配置区别

假设您的网站主页文件存放在 /var/www/sumingcheng 目录下,而管理系统的文件存放在 /var/www/sumingcheng-admin 目录下。

使用 root 指令配置主页

对于网站的主页(sumingcheng.cn),我们使用 root 指令。这意味着所有到根 URL 的请求都会映射到 /var/www/sumingcheng 目录。

server {
listen 80;
server_name sumingcheng.cn;

# 配置主页
location / {
root /var/www/sumingcheng;
index index.html index.htm;
}
}

在这个配置中,当用户访问 http://sumingcheng.cn 时,Nginx 将会从 /var/www/sumingcheng/index.html 加载主页。

使用 alias 指令配置管理系统

对于管理系统(sumingcheng.cn/admin),使用 alias 指令。这意味着所有到 /admin URL 的请求都会映射到 /var/www/sumingcheng-admin 目录。

server {
listen 80;
server_name sumingcheng.cn;

# 配置主页
location / {
root /var/www/sumingcheng;
index index.html index.htm;
}

# 配置管理系统
location /admin/ {
alias /var/www/sumingcheng-admin/;
index index.html index.htm;
}

# 其他配置...
}

在这个配置中,当用户访问 http://sumingcheng.cn/admin 时,Nginx 将会从 /var/www/sumingcheng-admin/index.html 加载管理系统的页面。

为什么不推荐使用 root 配置 admin 呢?

使用 root 配置 admin 路由是可以的,但这在某些情况下可能会导致路径解析问题,特别是当子目录的物理路径与 URL 路径不完全一致时。这正是 alias 指令更受欢迎的原因之一。

先解释一下,什么是子目录的物理路径与 URL 路径不完全一致

子目录的物理路径与 URL 路径一致

如果你使用 root /var/www; 并且 URL 路径与文件系统路径一致

  1. URL 路径:http://sumingcheng.cn/admin
  2. 文件系统路径:/var/www/admin

这种情况下,当用户访问 http://sumingcheng.cn/admin,Nginx 会在 /var/www/admin 路径下查找文件,这是因为 URL 路径 /admin 直接映射到了 /var/www/admin

子目录的物理路径与 URL 路径不一致

但在你的情况中,你想要的映射关系是

  1. URL 路径:http://sumingcheng.cn/admin
  2. 文件系统路径:/var/www/sumingcheng-admin

这里,URL 路径 /admin 并不直接对应于文件系统中的 /var/www/admin 路径,而是对应于 /var/www/sumingcheng-admin。这就是所谓的“物理路径与 URL 路径不完全一致”。

使用 root 配置子目录

当使用 root 配置子目录(比如 /admin)时,Nginx 会将整个 URL 路径附加到 root 指令指定的路径后面。这意味着,如果你的 root 配置是 /var/www/sumingcheng-admin,并且用户访问 http://sumingcheng.cn/admin/index.html,Nginx 会尝试在 /var/www/sumingcheng-admin/admin/index.html 找到该文件。这可能并不是你想要的,因为实际的文件可能就在 /var/www/sumingcheng-admin/index.html

使用 alias 配置子目录

相比之下,alias 指令允许你将一个特定的 URL 路径(如 /admin)映射到服务器上的一个不同的路径。这意味着,如果你的 alias 配置是 /var/www/sumingcheng-admin/,当用户访问 http://sumingcheng.cn/admin/index.html 时,Nginx 会直接在 /var/www/sumingcheng-admin/index.html 查找该文件,这正是我们期望的结果。

有几种情况下不建议使用 root 指令

  1. URL 路径与文件系统路径不一致:当你想将特定的 URL 路径映射到服务器上的一个不同的文件系统路径时,这种情况下使用 root 可能导致路径错误。例如,如果你想通过 URL http://sumingcheng.cn/admin 访问 /var/www/special-admin 目录下的内容,使用 root 将导致 Nginx 尝试在 /var/www/special-admin/admin 中查找文件,而实际你希望它直接查找 /var/www/special-admin
  2. 需要特定的子路径映射:如果你的应用需要将多个 URL 子路径映射到完全不同的文件系统路径,使用 root 将无法满足需求。例如,如果 /images 应该映射到一个路径,而 /scripts 映射到另一个完全不同的路径,root 将无法实现这种映射。
  3. 避免不必要的嵌套目录:使用 root 有时会导致文件路径解析出现不必要的嵌套。例如,如果配置了 root /var/www; 和一个指向 /adminlocation 块,Nginx 会尝试在 /var/www/admin 中查找 /admin 的内容,这可能并不是实际的文件路径。

什么情况下推荐使用 root 指令

  1. 整站映射:当你的整个网站或应用位于一个单一的文件系统目录下,并且 URL 路径直接映射到这个目录结构时,使用 root 是最简单和直接的方法。例如,如果你的网站文件全部位于 /var/www/mywebsite 目录下,那么使用 root /var/www/mywebsite; 是最合适的。
  2. 简单的 URL 结构:对于简单的、没有复杂子目录映射需求的网站,root 提供了一个干净和高效的解决方案。因为在这种情况下,每个 URL 路径都直接对应于文件系统中的一个相同的路径。

跨域到底跨了什么域

· 阅读需 2 分钟
素明诚
Full stack development

在网络编程和 Web 开发的背景下,"域"(Domain)通常指的是互联网上的一个命名区域,这通常对应于一个域名(如 sumingcheng.com)。但在涉及跨域(Cross-Origin)问题时,"域"或"源"(Origin)的概念更加具体,它不仅包括域名,还包括协议(如 HTTP 或 HTTPS)和端口号。这三部分共同构成了一个完整的"源"。

所以,跨域这个词我们不妨理解成跨源,那么源就好解释了。

同源策略

当涉及到同源策略时,只有当这三个部分(协议、域名、端口号)完全一致时,两个 URL 才被认为是来自同一个"源"。如果任何一部分不同,那么它们就属于不同的"源"。

为什么要有同源策略?

核心是为了保证服务器的安全,例如

跨站脚本攻击(XSS)

  • 如果浏览器允许脚本自由地访问跨源数据,恶意网站就可以通过注入脚本来窃取其他网站的敏感信息(如 cookies、session tokens 等)。这种攻击通常在用户不知情的情况下发生,可能导致隐私泄露和安全风险。

跨站点请求伪造(CSRF)

  • 如果跨源请求没有适当的限制和验证,攻击者可以伪造用户的请求,例如在用户登录银行网站时,恶意网站可能在后台发起转账请求。这种攻击利用了用户的登录状态和网站对用户身份的信任。

保护用户数据

  • 同源策略阻止了一个源的网页访问另一个源的敏感数据,包括存储在浏览器中的数据,如 LocalStorage、IndexedDB 和 Web SQL 数据库。

隔离潜在恶意内容

  • 限制脚本跨源通信有助于隔离和限制潜在的恶意内容,提高网站和用户的整体安全性。

Koa 和 Express 框架区别

· 阅读需 2 分钟
素明诚
Full stack development

Koa:洋葱模型

Koa 框架使用一种称为“洋葱模型”的中间件结构。这意味着在处理请求时,代码会“深入”每个中间件,然后在返回响应之前再“回溯”通过这些中间件。这种结构非常适合复杂的异步逻辑,因为它允许您在请求和响应期间执行代码。

Koa 中间件

const Koa = require('koa');
const app = new Koa();

// 第一个中间件
app.use(async (ctx, next) => {
console.log('中间件1 Start');
await next(); // 进入下一个中间件
console.log('中间件1 End'); // 在回溯时执行
});

// 第二个中间件
app.use(async (ctx, next) => {
console.log('中间件2 Start');
await next(); // 这里可以是异步操作
console.log('中间件2 End'); // 在回溯时执行
});

app.listen(3000);

执行顺序是

  1. 打印 "中间件 1 Start"
  2. 进入第二个中间件,打印 "中间件 2 Start"
  3. 第二个中间件完成后,打印 "中间件 2 End"
  4. 回到第一个中间件,打印 "中间件 1 End"

Express:线性流程

与 Koa 不同,Express 的中间件遵循一个更直线式的流程。在 Express 中,中间件按照它们添加到应用程序中的顺序执行。每个中间件处理请求,然后将控制权传递给下一个中间件,而不是返回到上一个中间件。

Express 中间件

const express = require('express');
const app = express();

// 第一个中间件
app.use((req, res, next) => {
console.log('中间件1');
next(); // 直接传递到下一个中间件
});

// 第二个中间件
app.use((req, res, next) => {
console.log('中间件2');
next(); // 传递控制权
});

app.listen(3000);

执行顺序是

  1. 打印 "中间件 1"
  2. 然后直接进入并打印 "中间件 2"

在这个结构中,没有类似于 Koa 中的“回溯”过程。每个中间件都是一个独立的单元,执行完毕后,就直接转到下一个中间件。

Nginx 配置示例

· 阅读需 1 分钟
素明诚
Full stack development
http {
# 基础配置
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;

# 日志配置
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;

# 服务器配置
server {
listen 80; # 监听端口
server_name localhost; # 服务器名

# 对 /http 请求的处理
location /http {
# URL 重写,移除 '/http'
rewrite ^/http/(.*) /$1 break;

# 代理设置
proxy_pass http://localhost:3335;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;

# 设置代理的头部信息
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}

# 默认处理
location / {
root html;
index index.html index.htm;
}

# 错误页面配置
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}

ORMObject-Relational Mapping对象关系映射

· 阅读需 2 分钟
素明诚
Full stack development

ORM,简单地说,就像是数据库和你的代码之间的翻译器。它让你能用你熟悉的 JavaScript 对象来处理数据,而不用去写那些有时候让人头疼的 SQL 语句。想象一下,你有个用户表,通常你得写 SQL 去添加、查找、更新或删除用户,对吧?但是有了 ORM,这一切就像是在处理一个普通的 JavaScript 对象。

比如说,你用 Sequelize(这是 Node.js 里一个很流行的 ORM 工具),你可以定义一个“User”模型,这个模型就代表了数据库里的用户表。然后,当你要创建一个新用户时,你只需要像操作 JavaScript 对象一样去做,Sequelize 会帮你把这些操作转换成相应的 SQL 语句。

这样做的好处是显而易见的:首先,你不需要花时间去写和调试 SQL 语句,这让你能更专注于编写业务逻辑;其次,因为你是在用 JavaScript 对象,所以代码的可读性也变得更好;最后,如果将来需要换数据库,你的代码改动会少很多,因为 ORM 会帮你处理数据库之间的差异。

用户表模型

const User = sequelize.define('User', {
username: DataTypes.STRING,
birthday: DataTypes.DATE
});

添加一条新纪录

User.create({
username: 'zhangsan',
birthday: new Date(1980, 6, 20)
});

不过,也有一些缺点。比如,对于一些复杂的查询,ORM 可能不够灵活,有时候生成的 SQL 语句也不是最优的。但总的来说,ORM 是个很有用的工具,尤其是在项目规模较大时,它能大大提升开发效率。

什么是 RESTful API

· 阅读需 2 分钟
素明诚
Full stack development

RESTful API(Representational State Transfer API)既是一种技术模式,也是一种设计标准或风格。它并不是一个正式的标准,而是一系列架构原则和约束条件的集合。

这些原则和约束条件旨在利用现有的 Web 技术和协议(如 HTTP),以一种简单、高效、可扩展、可靠和可移植的方式来设计和开发分布式系统。RESTful API 强调资源的表现层和客户端-服务器之间的无状态通信,目的是提高网络应用的性能、可伸缩性和简化修改。它已成为开发 Web 服务的流行方法。

实际使用

比如我们某个请求的接口,可能是以下这几种形式

# 获取 notes
GET /notes
# 获取 notes id 的数据
GET /notes/id

这种接口,我们是不用考虑服务端内部是怎么实现的,只需要知道这是彼此交互的接口

客户端不知道服务器到底有多少个中间层,也不需要知道

某些请求,比如 get /notes 可以在客户端或者服务端缓存一段时间

遵循以上的这些原则,就是 RESTful API

RESTful API 中文叫什么?

RESTful API 翻译成中文通常被称作“表现层状态转移应用编程接口”。这里,“表现层”指的是资源的表现层,即资源的具体表示形式(如 JSON、XML 等);“状态转移”则是指通过 HTTP 动词(如 GET、POST、PUT、DELETE 等)来表达对资源的操作,实现应用的状态转换。这种设计风格强调资源的识别、通过标准的 HTTP 方法进行操作,以及无状态通信,是构建 Web 服务的一种流行方法。