| 操作系统 | 版本 | 发布时间 | 支持设备 |
| macOS ??? | 26 | 2025年6月 | |
| macOS Sequoia | 15 | 2024年6月 | iMac (2019 年及后续机型) Mac Pro (2019 年及后续机型) iMac Pro (2017 年及后续机型) Mac Studio (2022 年及后续机型) MacBook Air (2020 年及后续机型) Mac mini (2018 年及后续机型) MacBook Pro (2018 年及后续机型) |
| macOS Sonoma | 14 | 2023年秋 | iMac (2019 年及后续机型) Mac Pro (2019 年及后续机型) iMac Pro (2017 年机型) Mac Studio (2022 年及后续机型) MacBook Air (2018 年及后续机型) Mac mini (2018 年及后续机型) MacBook Pro (2018 年及后续机型) |
| macOS Ventura | 13 | 2022年10月 | iMac (2017 年及后续机型) Mac Pro (2019 年及后续机型) iMac Pro (2017 年机型) Mac Studio (2022 年机型) MacBook Air (2018 年及后续机型) Mac mini (2018 年及后续机型) MacBook Pro (2017 年及后续机型) MacBook (2017 年机型) |
| macOS Monterey | 12 | 2021年6月8日 | iMac (2015 年末及后续机型) Mac Pro (2013 年末及后续机型) iMac Pro (2017 年及后续机型) Mac mini (2014 年末及后续机型) MacBook Air (2015 年初及后续机型) MacBook (2016 年初及后续机型) MacBook Pro (2015 年初及后续机型) |
| macOS Big Sur | 11 | 2020年6月23日 | MacBook (2015 年或后续机型) MacBook Air (2013 年或后续机型) MacBook Pro (2013 年后期或后续机型) Mac mini (2014 年或后续机型) iMac (2014 年或后续机型) iMac Pro (2017 年或后续机型) Mac Pro (2013 年或后续机型) |
| macOS Catalina | 10.15 | 2019年10月8日 | MacBook (2015 年前期或之后的机型) MacBook Air (2012 年中期或之后的机型) MacBook Pro (2012 年中期或之后的机型) Mac mini (2012 年后期或之后的机型) iMac (2012 年后期或之后的机型) iMac Pro (2017 年) Mac Pro (2013 年后期或之后的机型) |
| macOS Mojave | 10.14 | 2018年6月5日 | MacBook (2015 年前期或之后的机型) MacBook Air (2012 年中期或之后的机型) MacBook Pro (2012 年中期或之后的机型) Mac mini (2012 年后期或之后的机型) iMac (2012 年后期或之后的机型) iMac Pro (2017 年) Mac Pro (2013 年后期的机型,以及支持特定 Metal 技术图形卡的 2010 年中期和 2012 年中期的机型) |
| macOS High Sierra | 10.13 | 2017年6月5日 | MacBook (2009 年后期或之后的机型) MacBook Pro (2010 年中期或之后的机型) MacBook Air (2010 年后期或之后的机型) Mac mini (2010 年中期或之后的机型) iMac (2009 年后期或之后的机型) Mac Pro (2010 年中期或之后的机型) |
| macOS Sierra | 10.12 | 2016年9月20日 | MacBook (2009 年后期或之后的机型) MacBook Pro (2010 年中期或之后的机型) MacBook Air (2010 年后期或之后的机型) Mac mini (2010 年中期或之后的机型) iMac (2009 年后期或之后的机型) Mac Pro (2010 年中期或之后的机型) |
| OS X El Capitan | 10.11 | 2015年9月29日 | MacBook (2015 年前期的机型) MacBook (2008 年后期的铝金属机型以及 2009 年前期或之后的机型) MacBook Pro (2007 年中期/后期或之后的机型) MacBook Air (2008 年后期或之后的机型) Mac mini (2009 年前期或之后的机型) iMac (2007 年中期或之后的机型) Mac Pro (2008 年前期或之后的机型) Xserve (2009 年前期的机型) |
| OS X Yosemite | 10.10 | 2014年10月17日 | |
| OS X Mavericks | 10.9 | 2013年10月23日 | iMac (2007 年中期或之后的机型) MacBook (2008 年后期的铝金属机型、2009 年前期或之后的机型) MacBook Pro (2007 年中后期或之后的机型) Xserve (2009 年前期) MacBook Air (2008 年后期或之后的机型) Mac mini (2009 年前期或之后的机型) Mac Pro (2008 年前期或之后的机型) |
| OS X Mountain Lion | 10.8 | 2012年7月25日 | iMac (2007 年中期或之后的机型) MacBook (2008 年后期的铝制机型、2009 年前期或之后的机型) MacBookPro(2007 年中期/后期或之后的机型) Xserve (2009 年前期) MacBook Air (2008 年后期或之后的机型) Mac mini (2009 年前期或之后的机型) Mac Pro (2008 年前期或之后的机型) |
| OS X Lion | 10.7 | 2010年10月20日 | |
| OS X Snow Leopard | 10.6 | 2008年6月9日 |
参考资料:
本文以 vue 3 为例,vue 2 同理。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>clipboard.js 在 vue.js 中使用</title>
</head>
<body>
<div id="app">
<ul>
<li v-for="item in list">
{{item}}
<button class="btn-cp" :value="item">复制</button>
</li>
</ul>
</div>
<script src="//xxx/vue/core-3.x.x/vue.global.js"></script>
<script src="//xxx/clipboard/clipboard.js-2.x.x/dist/clipboard.min.js"></script>
<script>
const app = Vue.createApp({
data: function () {
return {
list: ["aaa", "bbb", "ccc"]
}
},
mounted: function () {
var clipboard = new ClipboardJS('.btn-cp', {
text: function (trigger) {
return trigger.getAttribute('value');
}
});
clipboard.on('success', function (e) {
alert('已复制“' + e.text + '”到粘贴板');
e.clearSelection();
});
}
});
const vm = app.mount('#app');
</script>
</body>
</html>第一步,创建用户和 AccessKey
登录阿里云控制台后,从头像处进入 AccessKey 管理

“开始使用子用户 AccessKey”

点击“创建用户”,填写用户名(本文以 oss-bbs 为例),并勾选“Open API 调用访问”

点击确定创建成功,可以看到 AccessKey ID 和 AccessKey Secret
第二步,创建权限策略
在阿里云控制台左侧菜单“RAM 访问控制”中展开“权限管理”,选择“权限策略”

点击“创建权限策略”,切换到“脚本编辑”

输入以下策略文档(JSON 格式)
{
"Version": "1",
"Statement": [
{
"Effect": "Allow",
"Action": [
"oss:ListBuckets",
"oss:GetBucketStat",
"oss:GetBucketInfo",
"oss:GetBucketAcl"
],
"Resource": "acs:oss:*:*:*"
},
{
"Effect": "Allow",
"Action": [
"oss:Get*",
"oss:Put*",
"oss:List*",
"oss:DeleteObject"
],
"Resource": "acs:oss:*:*:bbs"
},
{
"Effect": "Allow",
"Action": [
"oss:Get*",
"oss:Put*",
"oss:List*",
"oss:DeleteObject"
],
"Resource": "acs:oss:*:*:bbs/*"
}
]
}脚本中第一段表示允许用户登录,第二段表示允许操作 Bucket,第三段表示允许操作 Bucket 内的文件对象。
示例中的 bbs 是 Bucket Name,请修改为自己的 Bucket 名称。
点击下一步,填写名称,确定即可。
第三步,添加用户权限
转到“用户”页面,在刚才创建的用户行“添加权限”

切换到“自定义策略”,将上一步创建的权限策略添加到右侧“已选择”区

确定。
相关信息:
You have no right to access this object because of bucket acl.
首先,禁止网站下所有 .php 等文件均不允许被访问到。
在 nginx 网站配置文件中,include enable-php-**.conf; 上方插入:
location ~ ^/.*\.(php|php5|py|sh|bash|out)$ { deny all; }其中,^ 匹配开始,/.* 匹配所有目录和文件名,\.(php|php5|py|sh|bash|out) 匹配文件后缀名,$ 匹配结束。
即便如此,仍然忽略了 nginx 中 .php 文件名后加斜杠仍然能访问到的情况,譬如我们访问这个网址:
https://xoyozo.net/phpinfo.php/abc.htmlnginx 仍然运行了 phpinfo.php,给了后门可趁之机,所以改进为:
location ~ ^/.*\.(php|php5|py|sh|bash|out)(/.*)?$ { deny all; }Discuz! X3.4 需要写入权限的目录:
/自研目录/upload/
/config/
/data/
/uc_client/data/
/uc_server/data/
/source/plugin/
但,这些都不重要,我们已经禁止了所有目录的 .php 访问了。
第二步,解禁需要直接被访问到的文件路径。
Discuz! X3.4 根目录下的 .php 文件都是入口文件,需要能够被访问到:
/admin.php
/api.php
/connect.php
/forum.php
/group.php
/home.php
/index.php
/member.php
/misc.php
/plugin.php
/portal.php
/search.php其它目录中需要被直接访问到的文件:
/archiver/index.php
/m/index.php
/uc_server/admin.php
/uc_server/avatar.php
/uc_server/index.php部分插件文件需要能够被直接访问到:
/source/plugin/magmobileapi/magmobileapi.php
/source/plugin/smstong/accountinfo.php
/source/plugin/smstong/checkenv.php另外如果有自建目录需要有 .php 访问权限,那么也需要在此处加白,本文以 /_/ 目录为例
最终拼成:工具
location ~ ^(?:(?!(/admin\.php|/api\.php|/connect\.php|/forum\.php|/group\.php|/home\.php|/index\.php|/member\.php|/misc\.php|/plugin\.php|/portal\.php|/search\.php|/archiver/index\.php|/m/index\.php|/uc_server/admin\.php|/uc_server/avatar\.php|/uc_server/index\.php|/source/plugin/magmobileapi/magmobileapi\.php|/source/plugin/smstong/accountinfo\.php|/source/plugin/smstong/checkenv\.php|/_/.*\.php))/.*\.(php|php5|py|sh|bash|out)(/.*)?)$ { deny all; }这里用到正则表达式中的“不捕获”和“负向零宽断言”语法,格式为:
^(?:(?!(允许的目录或文件A|允许的目录或文件B))禁止的目录和文件)$值得注意的是,此句负向零宽断言中的匹配内容是匹配前缀的,也就是说
https://xoyozo.net/index.php
https://xoyozo.net/index.php/abc.html都可以访问到,而
https://xoyozo.net/forbidden.php
https://xoyozo.net/forbidden.php/abc.html都访问不到,这是符合需求的。
如果自建目录 /_/ 下有写入需求,单独禁止即可,以 /_/upload/ 为例:
location ~ ^/_/upload/.*\.(php|php5|py|sh|bash|out)(/.*)?$ { deny all; }ThinkPHP 网站有统一的访问入口,可按本文方法配置访问权限。
特别注意:上面的代码必须加在 PHP 引用配置(include enable-php-**.conf;)的上方才有效。
本文使用 ASP.NET 6 版本 Senparc.Weixin.Sample.MP 示例项目改造。
第一步 注册多公众号
方法一:打开 appsettings.json 文件,在 SenparcWeixinSetting 节点内添加数组节点 Items,该对象类型同 SenparcWeixinSetting。
//Senparc.Weixin SDK 设置
"SenparcWeixinSetting": {
"IsDebug": true,
"Token": "",
"EncodingAESKey": "",
"WeixinAppId": "",
"WeixinAppSecret": "",
"Items": [
{
"IsDebug": true,
"Token": "a",
"EncodingAESKey": "a",
"WeixinAppId": "a",
"WeixinAppSecret": "a"
},
{
"IsDebug": true,
"Token": "b",
"EncodingAESKey": "b",
"WeixinAppId": "b",
"WeixinAppSecret": "b"
}
]
}方法二:修改 Program.cs 文件,在 UseSenparcWeixin 方法中注册多个公众号信息。
var registerService = app.UseSenparcWeixin(app.Environment,
null /* 不为 null 则覆盖 appsettings 中的 SenparcSetting 配置*/,
null /* 不为 null 则覆盖 appsettings 中的 SenparcWeixinSetting 配置*/,
register => { /* CO2NET 全局配置 */ },
(register, weixinSetting) =>
{
//注册公众号信息(可以执行多次,注册多个公众号)
//register.RegisterMpAccount(weixinSetting, "【盛派网络小助手】公众号");
foreach (var mp in 从数据库或配置文件中获取的公众号列表)
{
register.RegisterMpAccount(new SenparcWeixinSetting
{
//IsDebug = true,
WeixinAppId = mp.AppId,
WeixinAppSecret = mp.AppSecret,
Token = mp.Token,
EncodingAESKey = mp.EncodingAeskey,
}, mp.Name);
}
});完成后,我们可以从 Config.SenparcWeixinSetting.Items 获取这些信息。
第二步 接入验证与消息处理
打开 WeixinController 控制器,将构造函数改写为:
public WeixinController(IHttpContextAccessor httpContextAccessor)
{
AppId = httpContextAccessor.HttpContext!.Request.Query["appId"];
var MpSetting = Services.MPService.MpSettingByAppId(AppId);
Token = MpSetting.Token;
EncodingAESKey = MpSetting.EncodingAESKey;
}示例中 Services.MPService.MpSettingByAppId() 方法实现从 Config.SenparcWeixinSetting.Items 返回指定 appId 的公众号信息。
为使 IHttpContextAccessor 注入生效,打开 Program.cs,在行
builder.Services.AddControllersWithViews();下方插入
builder.Services.AddHttpContextAccessor();这样,我们就可以在构造函数中直接获取地址栏中的 appId 参数,找到对应的公众号进行消息处理。
第三步 消息自动回复中的 AppId
打开 CustomMessageHandler.cs,将
private string appId = Config.SenparcWeixinSetting.MpSetting.WeixinAppId;
private string appSecret = Config.SenparcWeixinSetting.MpSetting.WeixinAppSecret;替换为:
private string appId = null!;
private string appSecret = null!;并在构造函数中插入
appId = postModel.AppId;
appSecret = Services.MPService.MpSettingByAppId(postModel.AppId).WeixinAppSecret;这样,本页中使用的 appId / appSecret 会从 postModel 中获取,而非默认公众号。postModel 已在 WeixinController 中赋值当前的 appId。
改造后,我们可以在 OnTextRequestAsync() 等处理消息的方法中可以判断 appId 来处理不同的消息。
第四步 其它功能和接口
其它功能和接口均可用指定的 AppId 和对应的 AppSecret 进行调用。
Senparc.Weixin.Sample.MP 盛派微信公众平台示例项目在 VS 中运行正常,当发布到 IIS 后出现应用程序池自动停止的情况,在服务器管理器中找到 .NET Runtime 错误,可以看到错误原因:
\App_Data\SenparcTraceLog 目录需要写入权限。

以下目录也需要写入权限:
\App_Data\WeChat_OfficialAccount
\App_Data\NeuChar
文件已正常部署且能正常访问到,但点击“文件已部署,立即认证”按钮时,然后被提示:访问文本资源失败,请调整后重试。原因是微信验证请求是 http 协议,如果网站强制启用 https 则无法完成验证。
在 ASP.NET 6 中可打开 Program.cs 文件,临时注释掉下行即可:
app.UseHttpsRedirection();在 Windows 11 电脑为例,通过无线网络连接 Wifi 网络,该网络是由多台路由器通过 AP 的方式连接,查看电脑连接的是哪台路由器,首先打开设置 - 网络和 Internet

点击属性,可以看到当前连接的网络频带和网络通道

图中可见,当前使用 149 信道连接网络。
打开 Vistumbler,点击 Scan APs,可以看到附近所有的 Wifi 信号

图中红框标出的是使用了相同 SSD 和密码的 AP 路由器,其中,我的电脑连接的是 149 信道对应的路由器,根据 MAC 地址、生产厂商等信息就可以判断是哪一台路由器了。
官方并没有“蓝牙钥匙”一说,平时讨论的蔚来蓝牙钥匙一般指:
1、智能钥匙(即物理钥匙)
2、蔚来 App 中的“蓝牙解锁启动”功能
本文指后者。
如果未开启“蓝牙解锁启动”,那么在 App 中解锁车门时,必须勾选“同时启动车辆”,否则是无法挂档的。
开启后,手机在车内即可将车开走。
所以在开启的情况下使用 App 解锁时,勾与不勾“同时启动车辆”效果是一样的。
ET7 开启蓝牙解锁启动后,手机靠近车辆会自动解锁(门把手需要按一下才能展开),EC6 必须打开 App 解锁车门。
那是不是说,如果手机丢了,ET7 也丢了?

App 5.3.6 | Aspen 3.1.2 | 2022年5月