阅读视图

发现新文章,点击刷新页面。
🔲 ☆

Baby Press — 前后端分离的WP系统

WP的系统怎么说呢,有时候真的感觉一言难尽,庞杂的功能,丰富的插件、主题。几乎能满足所有人的需求,当然,也能满足我的需求。

之所以要做这么个东西,最主要的是前几天在杜老师的聊天室收到一条消息:

跟随这条消息我也去了解了一下这个东西,按照官方的说法,其实是这么个东西:

Cloudflare 将这款项目命名为 EmDash,将其定位为 WordPress 的精神继承者,这并不是对 WordPress 简单的复刻,而是用现代化技术栈,重新实现一套面向未来的 CMS,并且重点解决了 WordPress 24 年发展中积累的的架构臃肿、安全隐患与性能瓶颈问题。

说是高性能的wp,但是实际上跟wp没有任何的关系,除了所谓的精神继承。刚开始我还以为是基于wp的优化,现在看来其实是完全做了另外一套系统,这精神继承,可以说是非常抽象了。

再加上 『爱看』在我没有丢失以前的网站数据的时候,就一直建议可以自己写个系统。重新搭建之后,他又提过几次:

既然 cf可以这么干,那么自己当然也可以这么干。只是,这次自己既不想重写,又不想使用php,于是,我换了最熟悉的django+vue3来实现这个新的系统,至于数据库当然还是用wp原来的。既然设计好这一切,那么声息的就是让ai开始动工了。

当然在开发过程中,不可避免的要面临一些问题,例如wp的shortcode,主题插件的一些功能:相册、代码高亮等等。不过这些东西都可以重新通过python进行处理和渲染。还有一些php的原生小组件渲染就有些困难了,这些只能通过其他方法进行实现。例如归属地、ua,访客信息等等。暂时尚未完成,为了处理ip归属地查询,目前将插件的归属地查询已经独立成了python服务,开源地址:https://cnb.cool/oba.by/baby-ip-location

测试地址:https://ip.zhongxiaojie.cn

当前测试页面效果:

访问地址:

https://i.zhongxiaojie.cn

代码暂未开源,还在继续完善。

🔲 ☆

Baby Anti-Spam 自建反垃圾评论系统

很久之前,就经常收到akismet的授权提醒,对应一个错误码10010。

刚开始还以为是多域名访问导致的授权校验出问题了。后来换了n个key,同时添加了插件hook掉所有的垃圾评论检测逻辑,让全部走统一的域名,结果前几天又收到这个提醒了。

插件代码:

<?php
/**
 * Plugin Name: Akismet 单一主域名(多域名站点)
 * Description: 当站点配置了多个域名时,强制发往 Akismet 的请求只使用一个主域名,避免被计为多站点触发 10010。
 * Version: 1.0
 * Author: obaby
 *
 * 使用:在下方设置 AKISMET_CANONICAL_HOME 为主域名(或留空则用 WordPress「设置」里的站点地址)。
 */

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

/**
 * 主域名(规范 URL,不要末尾斜杠)。留空则使用 get_option( 'home' )。
 * 例如: https://www.example.com
 */
if ( ! defined( 'AKISMET_CANONICAL_HOME' ) ) {
    define( 'AKISMET_CANONICAL_HOME', 'https://zhongxiaojie.cn' );
}

/**
 * 获取发往 Akismet 时使用的唯一主域名 URL。
 */
function akismet_single_domain_get_canonical_home() {
    $home = AKISMET_CANONICAL_HOME;
    if ( $home === '' || $home === null ) {
        $home = get_option( 'home' );
    }
    return untrailingslashit( $home );
}

/**
 * 将任意 URL 替换为使用主域名的版本(只改 host,保留 path/query)。
 */
function akismet_single_domain_normalize_url( $url, $canonical_home ) {
    if ( empty( $url ) || ! is_string( $url ) ) {
        return $url;
    }
    $parsed = wp_parse_url( $url );
    $canon  = wp_parse_url( $canonical_home );
    if ( empty( $canon['scheme'] ) || empty( $canon['host'] ) ) {
        return $url;
    }
    $scheme = isset( $parsed['scheme'] ) ? $parsed['scheme'] : $canon['scheme'];
    $host   = $canon['host'];
    $path   = isset( $parsed['path'] ) ? $parsed['path'] : '/';
    $query  = isset( $parsed['query'] ) ? '?' . $parsed['query'] : '';
    $frag   = isset( $parsed['fragment'] ) ? '#' . $parsed['fragment'] : '';
    return $scheme . '://' . $host . $path . $query . $frag;
}

/**
 * 统一 verify-key / get-subscription / get-stats 的 blog 为主域名。
 */
add_filter( 'akismet_request_args', function ( $request_args, $path ) {
    $paths = array( 'verify-key', 'get-subscription', 'get-stats' );
    if ( ! in_array( $path, $paths, true ) ) {
        return $request_args;
    }
    $canon = akismet_single_domain_get_canonical_home();
    if ( ! empty( $request_args['blog'] ) ) {
        $request_args['blog'] = $canon;
    }
    return $request_args;
}, 10, 2 );

/**
 * 统一 comment-check(以及 recheck)的 blog、permalink,并把请求里的 HTTP_HOST 等改为主域名。
 */
add_filter( 'akismet_request_args', function ( $request_args, $path ) {
    if ( $path !== 'comment-check' ) {
        return $request_args;
    }
    $canon = akismet_single_domain_get_canonical_home();
    $parsed = wp_parse_url( $canon );
    if ( empty( $parsed['host'] ) ) {
        return $request_args;
    }
    $canon_host = $parsed['host'];

    $request_args['blog'] = $canon;
    if ( ! empty( $request_args['permalink'] ) ) {
        $request_args['permalink'] = akismet_single_domain_normalize_url( $request_args['permalink'], $canon );
    }

    // 让服务端看到的“当前请求”也统一为主域名,减少被计为多站点
    if ( isset( $request_args['HTTP_HOST'] ) ) {
        $request_args['HTTP_HOST'] = $canon_host;
    }
    if ( isset( $request_args['REQUEST_URI'] ) ) {
        $uri = $request_args['REQUEST_URI'];
        $request_args['REQUEST_URI'] = ( is_string( $uri ) && ( $p = wp_parse_url( $uri, PHP_URL_PATH ) ) !== null ) ? $p : '/';
    }
    if ( isset( $request_args['DOCUMENT_URI'] ) ) {
        $uri = $request_args['DOCUMENT_URI'];
        $request_args['DOCUMENT_URI'] = ( is_string( $uri ) && ( $p = wp_parse_url( $uri, PHP_URL_PATH ) ) !== null ) ? $p : '/';
    }
    return $request_args;
}, 10, 2 );

/**
 * 统一 submit-spam / submit-ham 的 blog、permalink。
 */
add_filter( 'akismet_request_args', function ( $request_args, $path ) {
    if ( ! in_array( $path, array( 'submit-spam', 'submit-ham' ), true ) ) {
        return $request_args;
    }
    $canon = akismet_single_domain_get_canonical_home();
    $request_args['blog'] = $canon;
    if ( ! empty( $request_args['permalink'] ) ) {
        $request_args['permalink'] = akismet_single_domain_normalize_url( $request_args['permalink'], $canon );
    }
    return $request_args;
}, 10, 2 );

这次授权的密钥撑得时间稍微长了点,但是最终还是收到了这个提醒,意思是需要订购商业版授权。我这个人站点为了发垃圾评论订购一个商业版授权,确实有些难以接受。

于是,我决定自建反垃圾评论系统,基于scikit-learn实现了现在的这套垃圾评论检测系统,训练数据一部分来源于github的开源数据,另外一个就是我自己博客的评论数据。为了保证样本正例和负例数量差别不至于过大,经过各种方式进行了多轮数据清洗。

如果想要评论识别更加准确,可以提供自己的博客评论数据,如果能提供垃圾评论更好。现在欠缺的主要是垃圾评论数据,正常的评论数据我已经提供几千条数据。

效果测试:

测试地址:https://anti-spam.zhongxiaojie.cn/test/spam

简介:

面向 中英混合 评论的 WordPress 垃圾识别方案:PHP 插件在评论入库前调用 本机 Python 服务,由小型多语种向量模型 + 分类器(或演示用规则)给出垃圾概率。

适合评论量不大、单机部署(例如 4 核 / 8GB RAM 的 Ubuntu),服务与 WordPress 同机时使用 127.0.0.1 即可。

目录结构:

baby_anti_spam/
├── README.md
├── screenshots/             # 文档:服务启动与 curl 自测示意
│   ├── service.png
│   └── test.png
├── service/                 # Python FastAPI 侧车服务
│   ├── .env.example
│   ├── requirements.txt
│   ├── requirements-ml.txt
│   ├── run.py
│   ├── app/
│   │   └── stats_backends/   # 统计存储:sqlite / mysql
│   └── scripts/
│       ├── init_stats_mysql.sql
│       └── init_stats_mysql.py
│       ├── train_sklearn.py
│       ├── download_embedding_model.py
│       └── download_embedding_model.sh
└── wordpress/baby-anti-spam/
    └── baby-anti-spam.php # WordPress 插件

关键配置:

| 变量 | 说明 |
|------|------|
| `SPAM_HOST` | 监听地址,同机建议 `127.0.0.1` |
| `SPAM_PORT` | 端口,默认 `8765` |
| `SPAM_API_SECRET` | **单密钥模式(兼容旧版)**:未配置 `SPAM_API_KEYS` 且未配置 `SPAM_API_KEYS_FILE` 时,仅此密钥有效,等价于 name=`default`、不限流(`max_rpm=0`)。与 WP 插件里填写的密钥一致 |
| `SPAM_API_KEYS` | **多密钥**:JSON 数组。每项为 `name`(唯一,用于统计与限流分组)、`key` 或 `secret`(与请求头一致)、`max_rpm` 或 `rpm`(每分钟最大请求数,`0` 表示不限制)。与 `SPAM_API_KEYS_FILE` 合并时:**先读文件条目,再追加本变量** |
| `SPAM_API_KEYS_FILE` | 可选,指向 JSON 文件,根节点为与上表相同结构的**数组**。文件必须存在,否则进程启动失败 |
| `SPAM_MODEL_PATH` | 训练得到的 `*.joblib` 路径;留空则取决于 `SPAM_FALLBACK_RULES` |
| `SPAM_FALLBACK_RULES` | 无模型文件时是否启用内置极简规则(演示用);生产训练后应设为 `false` 并配置 `SPAM_MODEL_PATH` |
| `SPAM_LABEL_THRESHOLD` | 可选,默认 `0.8`。`spam_score` ≥ 此值时 JSON 中 `label` 为 `spam`,否则为 `normal` |
| `SPAM_DFA_ENABLED` | 默认 `true`。为 `true` 时使用 `dfa-python-filter/keywords` 做敏感词检测;命中则直接 `spam_score=1`、`detail=dfa_sensitive`(早于 sklearn) |
| `SPAM_DFA_KEYWORDS_PATH` | 可选,自定义敏感词文件路径;留空则用 `service/dfa-python-filter/keywords` |
| `SPAM_NON_CHINESE_FLOOR_ENABLED` | 默认 `true`。为 `true` 时若合并后的 author/email/url/text 中**无任何 CJK 表意字符**(主要针对中文训练语料),则将 `spam_score` **至少**抬到 `SPAM_NON_CHINESE_SPAM_FLOOR` |
| `SPAM_NON_CHINESE_SPAM_FLOOR` | 默认 `0.9`。与上项配合,在「无中文」评论上与 sklearn / 规则分取 `max` |
| `SPAM_STATS_ENABLED` | 默认 `true`。为 `true` 时记录每次**成功**返回的 `/v1/classify` 请求与响应(失败 / 401 不落库),并允许 `/v1/mark-spam` 写入 `spam_marks` 表 |
| `SPAM_STATS_BACKEND` | `sqlite`(默认)或 `mysql`。选 `mysql` 时需安装 `pymysql`(已在 `requirements.txt`)并配置下方 MySQL 变量 |
| `SPAM_STATS_DB_PATH` | 仅 `sqlite`:数据库文件路径;留空则为 `service/data/stats.sqlite`(已加入 `.gitignore`) |
| `SPAM_STATS_MYSQL_HOST` / `SPAM_STATS_MYSQL_PORT` | 仅 `mysql`:默认 `127.0.0.1` / `3306` |
| `SPAM_STATS_MYSQL_USER` / `SPAM_STATS_MYSQL_PASSWORD` | 仅 `mysql`:连接账号(`user` 必填) |
| `SPAM_STATS_MYSQL_DATABASE` | 仅 `mysql`:库名(必填),默认示例 `baby_spam_stats` |
| `SPAM_STATS_MYSQL_CHARSET` | 仅 `mysql`:默认 `utf8mb4` |

 

系统服务启动截图:

wp插件配置:

项目地址:https://anti-spam.zhongxiaojie.cn

代码地址:https://cnb.cool/oba.by/baby-wp-anti-spam

说明:如果自己不想训练数据,下载发布版的spam_pipeline.joblib 放入指定目录下配置服务启动即可,baby-anti-spam.zip 为wp插件。

训练耗时大约11分钟:

🔲 ☆

WP 访客信息插件 v16.06.99

### v16.06.99

- 版本号更新至 16.06.99
- 新增 **纯真QQWRY** IP 查询方式(qqwry_api:qqwry.dat / ipv6wry.db),无需 Composer
- 新增 **显示协议类型** 选项:在国旗与国家文本后、IP 地址前显示 IPv4/IPv6 图标(img/ipv4.png、ipv6.png)
- QQWRY(IPv4/IpLocation、IPv6/ipdbv6)与 ip2region(xdb)返回完整字段,支持国旗与完整归属地显示
- 图标样式统一:IP 版本图标与 IP 地址图标使用与浏览器/系统图标相同的 vertical-align 等样式

昨天发布了之后,hary反馈说,有更精准的纯真的数据库

当然啦,除此之外,其他的宝子的反馈我也看了,包括对于归属地准确性讨论的。

有的宝子的评论还没来的及回复,后面会回复的哈。在忙着测试hary提供的版本,不过整体测试下来,这个版本的qqwry版本的数据v6归属地精度,的确提高了一大截。

在集成了qqwry版本的数据库之后,目前已经有四种归属地查询方法,大家可以选择自己喜欢的。

并且添加了是否显示协议版本图标的功能,可以显示访客的网络类型。

图标位于插件的img目录下,如果想使用其他图标,直接替换目录下对应的ipv4.png 和ipv6的png即可。

已经内置几组图标,如果要想只显示ipv6的图标,可以用一个空白图标来替换ipv4图标即可。

插件代码:

https://cnb.cool/oba.by/wp-useragent

最新版(插件包含多个ip数据库,尽量使用ftp或者scp上传,wp后台上传可能失败):

https://cnb.cool/oba.by/wp-useragent/-/releases/tag/16.06.99

🔲 ☆

新年新气象:网站快一点,再快一点

WordPress 如果没有缓存,就会加载得超级慢。此前,我在网站上装了 Jetpack Boost、WP Super Cache 等插件。昨晚看到 此前发的文章,发现还能装一个 Redis Object Cache。

插件装得越来越多,我问 ChatGPT 有没有必要装这么多插件,它向我推荐了一种方案。如今,网站的访问速度基本得到了改善。秒开估计还是有些困难。

测速全绿(全部深绿还有点难)

Fastcgi Cache

WordPress 上的缓存插件都是在 PHP 运行的过程中起作用的,Fastcgi 缓存可以将服务器的缓存前置到 Nginx,如果 Nginx 匹配到缓存文件直接返回,请求不会给到 PHP。

在站点的 Nginx 配置文件伪静态部分后面加上如下片段,其中加粗部分为缓存的有效时间。

    set $skip_cache 0;
    if ($request_method = POST) { set $skip_cache 1; }
    if ($http_cookie ~* "wordpress_logged_in_") { set $skip_cache 1; }
    if ($request_uri ~* "/wp-admin/|/wp-login.php|/xmlrpc.php") { set $skip_cache 1; }
    if ($args != "") { set $skip_cache 1; }

    location ~ \.php$ {
        include fastcgi_params;
        fastcgi_pass unix:/tmp/php-cgi-85.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

        fastcgi_cache WORDPRESS;
        fastcgi_cache_key "$scheme$request_method$host$request_uri";
        <strong>fastcgi_cache_valid 200 301 302 30m;
        fastcgi_cache_valid 404 1m;</strong>
        fastcgi_cache_bypass $skip_cache;
        fastcgi_no_cache $skip_cache;

        add_header X-Cache $upstream_cache_status;
    }

在 Nginx 的全局配置文件中加上如下片段。

fastcgi_cache_path /www/wwwroot/fastcgi_cache levels=1:2 keys_zone=WORDPRESS:100m inactive=60m;
fastcgi_cache_key "$scheme$request_method$host$request_uri";

Gzip 和 Brotli 压缩

知道创宇的加速乐本就有 Gzip 自动压缩的功能,默认开启且无法关闭。皓子的 静态资源预压缩:零运行时开销,极致节省带宽 这篇文章给我提供了一种可能的优化路径。因为原先安装的 Nginx 并没有带 Brotli 模块,所以我卸载掉重新编译安装了一个。

然后 apt 安装 Brotli,在网站目录里搜索 js、css 文件并生成其对应的 gz、br 文件。

随后,在 Nginx 站点配置文件中添加关于 Gzip 和 Brotli 压缩的设置。

brotli on; brotli_static on; brotli_comp_level 5;
brotli_types text/plain text/css application/javascript application/json application/xml text/html image/svg+xml;

gzip on; gzip_static on; gzip_vary on; gzip_comp_level 5;
gzip_types text/plain text/css application/javascript application/json application/xml text/html image/svg+xml;

但可能是因为 CDN,我并没能测试到服务器返回 br encoded 的内容。

WordPress的插件

弄好上面的缓存和压缩之后,把 WP Super Cache 插件移除掉网站访问起来也不会太卡。目前网站正在用这些优化速度的插件:

插件名用途
Advanced Database Cleaner清理修订版本等垃圾数据
CompressX提供图片的webp和avif版本
Redis Object Cache网站目前使用的唯一缓存插件

新年新气象:网站快一点,再快一点最先出现在林林杂语

🔲 ⭐

WordPress服务器权限与所有权配置详解

a person using a laptop

核心概念:所有权 > 权限

在Linux中,权限(755/644)必须配合正确的所有权(User:Group)才能生效。换言之,PHP进程(即WordPress)必须是文件/目录的“所有者”,才能在755/644权限下进行写入(上传图片、升级插件、生成缓存)。

标准化操作流程

确保位于WordPress根目录(通常为/var/www/htmlpublic_html)下执行。

第一步:修正所有权

对当前目录下所有文件的所有者和组,行统一之设定。兹以33 (www-data) 为例(后文同此)。

chown -R 33:33 .

第二步:批量重置目录权限

按:使用+模式代替\;可显著提高执行效率。

find . -type d -exec chmod 755 {} +

第三步:批量重置文件权限

find . -type f -exec chmod 644 {} +

第四步:关键文件安全加固

针对敏感文件设置更严格的只读权限。

# wp-config.php 包含数据库密码,生产环境应设为 440 或 400
# 前提:文件所有者必须是 PHP 运行用户,否则设为 400 后 PHP 无法读取将导致网站无法访问
chmod 440 wp-config.php

# .htaccess 控制伪静态,通常设为 644,若不频繁修改可设为 604
chmod 644 .htaccess

针对部分具体插件的特殊分析

按,任何要求设置777权限的插件通常都存在设计缺陷与安全隐患。

但在应用上述“严格权限”时,以下插件模块可能会遇到权限阻碍:

缓存类:Super Cache (超级缓存)

该插件需要向wp-config.php写入开启缓存的定义代码,并修改.htaccess。当wp-config.php被设置为440时,插件后台更新设置会报错或白屏。是故,作为运维策略:

  1. 配置/更新插件前:chmod 644 wp-config.php
  2. 完成配置后:chmod 440 wp-config.php

按:日常运行中,插件生成的静态文件在wp-content/cache,该目录保持755即可正常读写。

翻译与本地化:Loco Translate

插件直接写入wp-content/languages目录生成.po/.mo文件。

只要第一步的chown -R 33:33 .执行正确,标准755目录权限即可满足需求。如果无法保存翻译,通常是所有者变成了别的(例如:在www-data才OK的情况下,所有者却变为了root)。

联邦宇宙与导入类 (ActivityPub, Import/Export)

  • 依赖:wp-content/uploads
  • 注意:导入大型XML/CSV或处理ActivityPub媒体流时,会产生临时文件。
  • 排查:如果导入失败或头像不显示,通过ls -ld wp-content/uploads检查权限是否为drwxr-xr-x (755)且所有者为www-data

另外,像WP File Manager这样的插件,虽然对于共享主机用户来说非常地便利,但其风险其实极高。如果该插件存在0-day漏洞,攻击者可绕过WordPress权限体系,直接以www-data身份操作服务器文件(上传Webshell),此时440644设置将失效。对于自托管用户来说,如已经拥有SSH命令行权限,该插件会增加不必要的攻击面。不如卸载。

常见故障排查清单

  1. 错误:440导致某些环境白屏

    如果服务器使用的不是PHP-FPM (User: www-data) 而是以CGI模式运行(User: 系统账户),将wp-config.php设为440且所有者为www-data(或33)可能导致文件无法被读取,引发HTTP 500错误。

    • 验证:执行完命令后,如果网站正常访问,说明配置正确。
  2. 插件更新失败 / 无法创建目录

    • 现象:后台提示“无法创建目录”。
    • 原因:通常不是权限问题(755是对的),而是所有权问题。
    • 复查:运行ls -ld wp-content/plugins,确保输出包含www-data www-data(或33 33)。如果显示的是root root,插件将无法更新。
  3. Git/开发环境

    如使用Git管理代码,.git目录的权限不要设置为755/644,且不应允许Web访问。宜在Nginx/Apache配置中显式禁止访问.git目录。

推荐操作脚本

确认在WordPress根目录后,按顺序执行:

# 1. 修正所有权 (兹以www-data为例,即id 33)
chown -R 33:33 .

# 2. 修正目录权限
find . -type d -exec chmod 755 {} +

# 3. 修正文件权限
find . -type f -exec chmod 644 {} +

# 4. 加固配置文件 (注意:配置 Super Cache 插件时可能需临时改为 640/644)
chmod 440 wp-config.php

# 5. 确保 .htaccess 对 WP 可写但安全
chmod 644 .htaccess

延伸阅读

🔲 ☆

禁用WordPress中Jetpack的AI助手按钮

自托管WordPress中安装了Jetpack插件后,会见到如牛皮癣般在文本写作的各个环节内嵌入于界面的“AI助手”。对于AI的态度本文不赘述——但是Jetpack的AI助手只会给每个新建的WordPress站点免费用那么几次。免费次数用光后,就需要购买增值服务。为产品付费无可厚非。但是如果不买,大剌剌的充值广告也仍然霸占网站后台界面,非常难看,横亘在那儿也不便于使用其他WordPress功能。

看到这儿,如果你也希望为站点内所有用户彻底禁用Jetpack的所有AI功能,可以将以下代码添加到主题的functions.php文件或使用Code Snippets插件:

add_filter( 'jetpack_ai_enabled', '__return_false' );

此代码通过调用Jetpack AI钩子直接关闭该模块。

又及:如何看待Jetpack?

征引一则Reddit回帖:

Comment
byu/PettyNiwa from discussion
inWordPress

如果你不是开发者,而且你没有那么多经验,那么Jetpack就很棒。如果你有经验,那么你可能不需要Jetpack…

我不认为Jetpack是坏事或好事,它只是为某些用户准备的,而对其他人来说,它是不需要的。

pimplyteen@Reddit
🔲 ☆

WordPress/MCP Adapter安装与维护指南

此指南适用于开发环境或通过Git管理的生产环境。Docker环境可用。

核心概念

MCP Adapter既可以作为Composer库被其他插件引用(推荐),也可以作为独立插件运行。

  • 依赖管理:该插件不包含vendor目录(第三方库),必须在本地通过Composer生成。
  • 运行环境:需要PHP 7.4+和WordPress 6.8+。

首次安装流程

步骤A:下载源码

进入WordPress的插件目录并克隆仓库:

cd /path/to/wp-content/plugins/
git clone https://github.com/WordPress/mcp-adapter.git
cd mcp-adapter

步骤B:安装依赖

此步骤用于生成vendor/autoload.php文件。若跳过此步,插件将无法运行。

Docker环境下的命令:

docker run --rm \
    -v $(pwd):/app \
    composer install

会下载wordpress/abilities-api等核心依赖并生成自动加载映射。

步骤C:激活插件

# 使用 WP-CLI 或在后台激活
wp plugin activate mcp-adapter

HTTPS协议一致性

配置WP_API_URL时,必须严格匹配站点的实际协议

  • ❌ 错误做法:站点强制 HTTPS,但填写http://yousite.com/...
  • ✅ 正确做法:填写https://yousite.com/...

如果站点强制使用 HTTPS(生产环境标准配置),而在配置中填写了http://,WordPress或服务器(Nginx/Apache)会返回一个301 Redirect跳转到HTTPS。在这个跳转过程中,出于安全规范,客户端发送的Authorization标头(包含密码)通常会被丢弃。这将导致请求虽然到达了最终地址,但因丢失凭据而报401 Unauthorized错误。

后续更新流程

由于插件通过Git安装,使用WordPress后台的“更新”按钮,以免覆盖Git配置。应按照以下步骤进行更新:

第一步:同步代码

获取最新的功能和修复:

cd /path/to/wp-content/plugins/mcp-adapter
git pull origin trunk

第二步:同步依赖

代码更新可能包含依赖包版本的变化(composer.lock变更)。每次git pull后运行:

docker run --rm \
    -v $(pwd):/app \
    composer install

如果跳过此步,可能会因为缺少新引入的类文件导致网站出现Fatal Error。

常见问题

  • Plugin could not be activated (Fatal Error):
    • 原因:忘记执行composer install,导致vendor/autoload.php缺失。
    • 解决:重新执行安装流程中的步骤B。
  • 类名冲突:
    • 原因:如果有多个插件都使用了MCP Adapter。
    • 解决:文档建议使用Jetpack Autoloader来解决多版本冲突(composer require automattic/jetpack-autoloader),但在单插件模式下非必须。
  • API 404 错误:
    • 解决:确保WordPress的固定链接(Permalinks)设置不是“朴素 (Plain)”,需要设置为“文章名 (Post name)”或其他结构。
  • API 401 错误 (Unauthorized):
    • 现象MCP error -32603: WordPress API error (401),且确认密码无误。
    • 解决:检查mcp.json中的WP_API_URL是否误写为了http://。将其修改为https://以避免重定向导致的凭据丢失。

延伸阅读

🔲 ☆

WordPress转换成Markdown(jekyll格式)

1.下载Node.js

访问 Node.js官网(https://nodejs.org), 下载完成后安装。

2.下载WordPress.xml 文件

在 WordPress 后台, 导出 xml 文件。

3.开始转换

新建一个文件夹, 把下载的xml文件改名为export.xml放到此文件夹中。

按住Shift右键文件夹空白处打开powershell

4.输入命令

npx wordpress-export-to-markdown

5.命令选项

Path to WordPress export file? export.xml
Put each post into its own folder? No
Add date prefix to posts? Yes
Organize posts into date folders? No
Save images? (Use arrow keys)?All Images

6.处理图片路径

因为我要把Markdown文件和图片上传到Github的jekyll目录格式,需要修改图片路径。

Node.js的wordpress-export-to-markdown处理过的文章目录是:posts下存放images和md文件,但是jekyll的目录是images和posts在同一级目录。需要把md文件的图片链接由(images/abc.jpg)改成 (/images/abc.jpg)。

按住Shift右键posts文件夹空白处打开powershell,输入以下命令:

Get-ChildItem -Recurse -Filter *.md | ForEach-Object {
    $content = Get-Content $_.FullName -Encoding UTF8 -Raw
    $content = $content -replace '!\[\]\((images/[^)]+)\)', '![](/$1)'
    Set-Content -Path $_.FullName -Value $content -Encoding UTF8
    Write-Host "已处理: $($_.FullName)" -ForegroundColor Green
}

7.上传到Github的文件夹中

将处理好的Markdown文件和图片上传至Github仓库中(浏览器上传或者Git推送都行)。

我的博客的GitHub Pages站点网址:https://jfsay.github.io

🔲 ☆

Cusdis - 轻量、保护隐私、开源的 Disqus 评论系统替代方案

由于之前将博客全静态化了导致评论无法使用,原本是不打算做的,但是还是又挺多朋友通过各种各样的渠道联系我交流问题,故打算解决一下这个问题,方便后续交流。

我的解决方案是能自建就自建,无法自建的基本上就不考虑了。Disqus 不能自建,加之实际使用起来效果并不理想,隐私问题,还有界面不太喜欢就直接被我 Pass 掉了。

相交于 Disqus,Commento++也是不错的解决方案,但是界面不太喜欢,以及不够轻量,故没有选择,综合来考虑来看,Cusdis是非常不错的解决方案,足够轻量、支持自建、UI简洁,致使我最终选择了 Cusdis。

此处介绍两种方式 Docker、手工部署 Cusdis,均基于宝塔面板。


项目介绍

项目地址:Cusdis

Cusdis是Disqus的开源、轻量级(约5kb gzip)、隐私友好的绝佳替代品,主要用于纯静态化网站。

Cusdis 并非旨在成为 Disqus 的完整替代品。它的目的是为小型网站(例如您的静态博客)实现一个极简主义和可嵌入的评论系统。

官方文档:Cusdis Docs

特性

  • Cusdis 是开源的并且可以自我托管。因此,您拥有自己的数据。
  • SDK 是轻量级的(~5kb gzipped)。
  • Cusdis 不需要您的用户登录即可发表评论。
  • Cusdis 根本不使用 cookie。

缺点:

  • Cusdis 正处于其开发的早期阶段。
  • 没有垃圾邮件过滤器,因此,您必须手动审核您的评论部分,并且在您批准之前不会显示评论。

其UI简洁、支持自托管、支持邮件推送,在邮件内即可进行批准以及回复是我比较看重的功能。


环境配置

由于 Cusdis 基于Node.js 开发,采用 SQLite 或 MySQL 或 Postgresql 数据库存储数据,所以配置要求如下:

  • 系统上需要安装 Node.js 和 yarn
  • 服务器上安装了 MySQL 或 Postgresql

本文基于宝塔面板,使用 SQLite 进行安装

安装配置 Node.js

如您已安装 Node.js 和yarn 并且配置成功,则此步可以跳过。

安装 Node.js 命令如下

1
2
3
4
5
6
cd /www/server/nodejs
#国外服务器选择
wget https://nodejs.org/dist/v14.15.0/node-v14.15.0-linux-x64.tar.gz
#国内服务器选择
wget https://registry.npmmirror.com/-/binary/node/v14.15.0/node-v14.15.0-linux-x64.tar.gz
tar -zvxf node-v14.15.0-linux-x64.tar.gz

设置 Node.js 全局变量:

在宝塔面板打开 /etc/profile 文件,将以下配置输入文件最后面,并保存

1
2
export NODE_HOME=/www/server/nodejs/node-v14.15.0-linux-x64
export PATH=$NODE_HOME/bin:$PATH

输入以下命令用于重载全局配置。

1
source /etc/profile

输入 node -v 和 npm -v 返回以下信息即配置完成

img配置成功

安装 yarn

1
npm install -g yarn

查看版本信息,如遇 yarn:未找到命令,请看:《NodeJS 和 npm 配置全局变量

国内服务器此步骤由于 Node.js 没有大陆节点,速度较慢。请耐心等待

千万不要使用淘宝的 registry 镜像源!!!!!!!!

否则安装依赖会出错!!!!!!!!

部署 Cusdis

此处介绍两种方式部署,手动部署与使用Dokcer

手动部署

一、克隆仓库

1
2
cd /www/wwwroot
git clone https://github.com/djyde/cusdis.git

img

二、安装 Cusdis 所需依赖

国内服务器此步骤由于 Node.js 没有大陆节点,速度较慢。请耐心等待

千万不要使用淘宝的 registry 镜像源!!!!!!!!

否则安装依赖会出错!!!!!!!!

1
2
cd cusdis
yarn install

img

三、配置 .env 文件

在 cusdis 文件夹中新建一个名为 .env 的文件

img

文件具体配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
USERNAME=admin
PASSWORD=password
JWT_SECRET=ofcourseistillloveyou
NEXTAUTH_URL=http://IP_ADDRESS_OR_DOMAIN
HOST=http://IP_ADDRESS_OR_DOMAIN
DB_TYPE=sqlite
DB_URL=file:./data.db
#以下配置为 EMAIL 配置 可选
SMTP_HOST=smtp.gmail.com
SMTP_PORT=465
SMTP_SECURE=true
SMTP_USER=your gmail email
SMTP_PASSWORD=<app password>
SMTP_SENDER=your gmail email

其中

为用户名
1
2
3
4
5
6
7
8
9
10
PASSWORD 为密码
JWT_SECRET 为 JWT 令牌
NEXTAUTH_URL 与 HOST 需要填写项目所用的域名/IP
DB_TYPE、DB_URL 为 数据库类型、数据地址
SMTP_HOST 为 SMTP 主机
SMTP_USER 为 SMTP 用户名
SMTP_PASSWORD 为 SMTP 密码
SMTP_SENDER 为发件人电子邮件地址
SMTP_PORT 为 SMTP 端口 默认为 587
SMTP_SECURE 为是否启用 SMTP 安全,默认值为true

img

四、构建 Cusdis

1
yarn run build:without-migrate

img

这一步可能会出现错误,错误代码如下:

1
2
3
4
5
6
7
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! cusdis@ db:generate: `prisma generate --schema ./prisma/$DB_TYPE/schema.prisma`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the cusdis@ db:generate script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

这一步需要到 ./cusdis/prisma 选择需要设置的数据库类型,然后将该文件夹内的 schema.prisma 文件 复制到 ./cusdis/prisma 构建即可解决。

五、运行 Cusdis

1
yarn run start:with-migrate

img

设置程序守护,此处以systemd为例

打开目录 /usr/lib/systemd/system/

新建文件:cusdis.service

文件配置如下(以下配置仅供参考):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[Unit]
Description=CusdisServer

[Unit]
Description=CusdisServer

[Service]
ExecStart=/www/server/nodejs/node-v14.15.0-linux-x64/bin/npm start
Restart=always
Environment=PATH=/usr/bin:/usr/local/bin:/www/server/nodejs/node-v14.15.0-linux-x64/bin
Environment=NODE_ENV=production
WorkingDirectory=/www/wwwroot/cusdis/

[Install]
WantedBy=multi-user.target

此时保存即可,运行:

1
2
3
4
5
6
# 更新配置
systemctl daemon-reload
# 启动服务
systemctl start cusdis
# 设置开机启动
systemctl enable cusdis

详细的管理命令如下:

1
2
3
4
5
6
7
8
9
10
11
12
# 启动服务
systemctl start cusdis
# 设置开机启动
systemctl enable cusdis
# 停止服务
systemctl stop cusdis
# 重启服务
systemctl restart cusdis
# 查看状态
systemctl status cusdis
# 更新配置
systemctl daemon-reload

Docker部署

一、获取镜像

镜像名如下:

1
djyde/cusdis

img

国内服务器获取镜像会极慢,请耐心等待。

二、创建容器

img

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
配置如下:
容器端口:3000
容器目录:/data
环境变量:
-e USERNAME=admin \
-e PASSWORD=password \
-e JWT_SECRET=ofcourseistillloveyou \
-e DB_URL=file:/data/db.sqlite \
-e NEXTAUTH_URL=http://IP_ADDRESS_OR_DOMAIN \
其中
USERNAME 为用户名
PASSWORD 为密码
JWT_SECRET 为 JWT 令牌
NEXTAUTH_URL 需要填写项目所用的域名/IP
DB_TYPE、DB_URL 为 数据库类型、数据地址

#以下配置为 EMAIL 配置 可选
SMTP_HOST=smtp.gmail.com
SMTP_PORT=465
SMTP_SECURE=true
SMTP_USER=your gmail email
SMTP_PASSWORD=<app password>
SMTP_SENDER=your gmail email

img

启动完成。

后语

设置反向代理

宝塔新建站点 -> 打开SSL - > 反向代理 ->添加反向代理

目标 URL 填写:http://127.0.0.1:3000

img

img

配置站点

进入页面登陆,然后创建一个默认的网站,选择 Embed Code ,复制代码到网站的合适位置即可。

img

WordPress 配置

以下配置仅供参考,主要包括 data-page-id、data-page-url、data-page-title

1
2
3
data-page-id="<?php the_ID(); ?>"
data-page-url="<?php $id =get_the_ID();echo get_permalink($id); ?>"
data-page-title="<?php the_title(); ?>"

跨域问题

最开始使用的时候可能会出现跨域问题。

在反向代理的配置文件中添加:

1
add_header 'Access-Control-Allow-Origin' 'yousitedomain';

两种方法,更推荐 DOCKER 如选择手工安装,可能会遇到各种各样的问题。

🔲 ☆

WordPress “纯”静态化

前几天才发表了 WordPress 的 CDN 方案,但是很快就反水了,并不是因为那个方案不够好,而是越写博客越发现,静态博客才是个人博客应有的终极形态。

很多朋友都在劝我抛弃 WordPress 转投 Hexo 的怀抱,不过确实,“纯”静态博客个人才是博客应有的样子。为什么要加一个“纯”呢?就像 WordPress,很多人通过伪静态,把页面后缀改为 html,再使 CDN 强制缓存,达到一个静态的效果。但这样的 伪静态 并非 静态博客 的真正样貌。

为什么不使用 Hexo 或者其他方案,因为仅 Hexo 对我来说是完全陌生的,而且其所使用的技术栈,也是我完全不懂的。相较于使用一些完全不懂的东西,不如去继续把手头正在用的改造的更好,毕竟内容才是博客最主要的。


方案选择

选择 WordPress 的理由

其实对于 WordPress 的理由有很多,无论是一些非常好用的插件,还是 Gutenberg,还是整个操作逻辑,对于软件使用的熟练使用程度,其所使用语言对目前我来说一些基本操作都能够实现。都在让我坚持使用 WordPress,以至于更换“纯”静态方案,没有将其替换掉的原因。

为什么要坚持所谓的”纯”静态

传统的 WordPress 加速解决方案都是使用 WP Super cache 之类的插件,生成缓存,然后生成 html 文件,使用 CDN 强制缓存,但这么做的问题是,虽然展示的是静态的,但其还是需要执行 SQL 语句来调用数据的,虽然目前市面上的 0SQL 主题不少,但是大多数还是无法避免这个操作。

而“纯”静态化,直接是 0SQL,无需后端,可以极大的缩少服务器资源的占用。就算你的服务器在海外,只要域名备案,通过国内的 CDN,都可以获取非常可观的速度。

目前方案的问题

目前方案主要拥有下面两个问题:搜索不可用以及评论不可用。

我对于这两个问题的解决直接放弃了。

本身国内的个人备案是不支持交互式网站的,而且垃圾评论实在是太多,以至于我后面开启了 reCAPTCHA,还是不断的有人来打广告。。。。

关于搜索,因为每个文章都拥有相应的 tag,点击一下即可显示相关文章,一部分承担了搜索的功能。

两个问题带来的影响都不算大,索性就不去管了,去专注内容。

更新不及时,需要手动去刷新 CDN 缓存。

Simply Static

插件地址:Simply Static

这是我目前所选择方案所使用到的插件,它最大的好处就是通过缓存可以直接将 WordPress 页面生成静态文件,并且可以将文件中的地址自动替换,直接放到服务器即可。

方案介绍

所需要的要求如下:

  • 需要用到两个域名:
    • console.domain.com //用于 WordPress 动态资源的域名
    • domain.com //用于静态博客域名(博客的主域名)
  • 两个站点都需要位于同一服务器内
  • 其余要求可以打开插件 Simply Static › Diagnostics 查看有哪些地方不符合规则

配置

Simply Static 设置

原理很简单,就是通过 Simply Static 这个插件,直接在 domain.com 也就是你博客的主域名的目录里生成静态文件。

这个插件,需要进行以下设置:

GENERAL

1、Destination URLs

此处的作用是将 WordPress 生成的静态文件中 动态博客地址,转为主博客的地址(静态地址)

img

此处需要选择 Use absolute URLs 然后填写你博客的主域名

2、Delivery Method

此处的作用,是选择把生成的静态文件通过何种方式存储。

img

此处选择:Local Directory

3、Local Directory

设置生成的静态文件存储的目录

img

此处填写 主博客所设置的目录即可。

INCLUDE/EXCLUDE

此处设置一处:Additional URLs

输入内容主要是不包含在静态页面中的链接,但还是需要生成静态文件的链接。

img

此处需要设置 动态博客 的文件链接。

主要是 sitemap、robots.txt

其他设置

其他设置可根据自身需要来进行设置,诸如可以设置:附加文件和目录、要排除的 URL、

临时文件目录、HTTP 基本身份验证(此处强推)

全部设置完毕后,可以在 Diagnostics 处进行检测,当没有错误即可进行手动生成。

生成静态文件

当设置完毕,并且检测没有问题后,在 Generate 中点击 GENERATE STATIC FILES 即可生成文件,根据需要生成的文件大小不同所需时间也不同。

img

CDN 设置

CDN 还是采用通过 DNS 区分国内国外用户,国内用户走腾讯云,国外用户走 CloudFlare。此处与之前的方案没有改变。

因为是是纯静态文件,所以无论国内还是国外的用户都会有非常不错的体验。

此处可以参考 《目前博客的 CDN 解决方案

无论是 腾讯云还是CloudFlare主要:

  • 设置防盗链
  • 开启强制缓存,并设置缓存过期时间
  • 设置浏览器缓存过期时间
  • 开启HTTPS
  • 打开 压缩静态文件

对整个网站做出更改后,可以通过 腾讯云CDN、CloudFlare 两个 WordPress 实现刷新缓存,目前无其他比较好的方法。

折腾来折腾去还是找到了对我还是对用户来说都最好的解决方案,接下来就是专心写文了。

🔲 ☆

使用 WP-CLI 更换 WordPress 域名

很多时候,WordPress 更换域名是一件及其麻烦的事情,一则需要手动去修改数据库,二则不确定是否会不会有漏掉修改的地方。(作为一个博客更换过十几个域名的小老铁深受其害)

WordPress官方推出了用于管理 WordPress 的命令行工具——WP-CLI,我们只需借助其中批量修改数据库的功能即可近乎完美的快速完成 WordPress 站点的域名修改。


WP-CLI配置要求

  • 类 UNIX 环境(OS X、Linux、FreeBSD、Cygwin),Windows 环境中的支持有限
  • PHP 5.6 或更高版本
  • WordPress 3.7 或更高版本。比最新 WordPress 版本更早的版本可能会降低功能

修改域名

一、安装 WP-CLI

使用以下命令进行安装配置 WP-CLI

1
2
3
4
5
#下载 WP-CLI
curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
#配置全局变量
chmod +x wp-cli.phar
sudo mv wp-cli.phar /usr/local/bin/wp

img

使用以下命令检测配置是否正常

1
wp --info

如果出现以下错误,则需要解禁 PHP函数:proc_open

img解禁PHP proc_open 函数即可解决

配置正常返回以下信息:

img配置正常

二、修改站点域名

打开 WordPress 站点目录(此处以宝塔默认为例,如您进行了其他配置,请修改

1
2
3
4
5
6
7
#打开站点目录
cd /www/wwwroot/wordpress
#测试站点需要修改的地方,此命令不会直接运行,以下命令二选一即可。
#此命令适用于 root 用户
wp search-replace 'http(s)://olddomain' 'http(s)://newdomain' --dry-run --allow-root
#此命令适用于非 root 用户
sodu -u wp search-replace 'http(s)://olddomain' 'http(s)://newdomain' --dry-run

返回以下信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
[root@localhost wordpress]# wp search-replace 'https://te1.roy.wang' 'https://te.roy.wang' --dry-run --allow-root
+------------------+-----------------------+--------------+------+
| Table | Column | Replacements | Type |
+------------------+-----------------------+--------------+------+
| wp_commentmeta | meta_key | 0 | SQL |
| wp_commentmeta | meta_value | 0 | SQL |
| wp_comments | comment_author | 0 | SQL |
| wp_comments | comment_author_email | 0 | SQL |
| wp_comments | comment_author_url | 0 | SQL |
| wp_comments | comment_author_IP | 0 | SQL |
| wp_comments | comment_content | 0 | SQL |
| wp_comments | comment_approved | 0 | SQL |
| wp_comments | comment_agent | 0 | SQL |
| wp_comments | comment_type | 0 | SQL |
| wp_links | link_url | 0 | SQL |
| wp_links | link_name | 0 | SQL |
| wp_links | link_image | 0 | SQL |
| wp_links | link_target | 0 | SQL |
| wp_links | link_description | 0 | SQL |
| wp_links | link_visible | 0 | SQL |
| wp_links | link_rel | 0 | SQL |
| wp_links | link_notes | 0 | SQL |
| wp_links | link_rss | 0 | SQL |
| wp_options | option_name | 0 | SQL |
| wp_options | option_value | 2 | PHP |
| wp_options | autoload | 0 | SQL |
| wp_postmeta | meta_key | 0 | SQL |
| wp_postmeta | meta_value | 0 | SQL |
| wp_posts | post_content | 2 | SQL |
| wp_posts | post_title | 0 | SQL |
| wp_posts | post_excerpt | 0 | SQL |
| wp_posts | post_status | 0 | SQL |
| wp_posts | comment_status | 0 | SQL |
| wp_posts | ping_status | 0 | SQL |
| wp_posts | post_password | 0 | SQL |
| wp_posts | post_name | 0 | SQL |
| wp_posts | to_ping | 0 | SQL |
| wp_posts | pinged | 0 | SQL |
| wp_posts | post_content_filtered | 0 | SQL |
| wp_posts | guid | 3 | SQL |
| wp_posts | post_type | 0 | SQL |
| wp_posts | post_mime_type | 0 | SQL |
| wp_term_taxonomy | taxonomy | 0 | SQL |
| wp_term_taxonomy | description | 0 | SQL |
| wp_termmeta | meta_key | 0 | SQL |
| wp_termmeta | meta_value | 0 | SQL |
| wp_terms | name | 0 | SQL |
| wp_terms | slug | 0 | SQL |
| wp_usermeta | meta_key | 0 | SQL |
| wp_usermeta | meta_value | 0 | PHP |
| wp_users | user_login | 0 | SQL |
| wp_users | user_nicename | 0 | SQL |
| wp_users | user_email | 0 | SQL |
| wp_users | user_url | 1 | SQL |
| wp_users | user_activation_key | 0 | SQL |
| wp_users | display_name | 0 | SQL |
+------------------+-----------------------+--------------+------+
Success: 8 replacements to be made.

确认需要修改的信息无误后,直接修改即可:

1
2
3
4
#此命令适用于 root 用户
wp search-replace 'http(s)://olddomain' 'http(s)://newdomain' --allow-root
#此命令适用于非 root 用户
sodu -u wp search-replace 'http(s)://olddomain' 'http(s)://newdomain'

img

至此数据域名修改域名完成。

这个通过 WP-CLI 修改域名还是十分方便的,但切莫忘记修改SSL、以及站点等相关信息。

🔲 ☆

WordPress 更换 Feed 类型

前段时间发表了 WebFeed倡议书,倡议书中关于 Feed 类型,推荐所有独立博主都使用 atom,但 WordPress 默认 Feed 类型使用的是 RSS。

关于如何切换为 atom,WordPress官方并没有给出解答,遍寻百度、谷歌等等没有搜索出关于切换 WordPress Feed类型的教程。遍寻WordPress代码终于找到了切换的地方。


切换 Feed 类型

WordPress 在 /wp-includes/feed.php 文件中大约89行处,定义了一个函数——default_feed,仅需将该函数第二个值从默认的 rss 设置为 atom 即可

img

Feed 类型对照表:

1
2
3
4
5
atom:           $default_feed = apply_filters( 'default_feed', 'atom' );
rss0.92: $default_feed = apply_filters( 'default_feed', 'rss' );
rss2: $default_feed = apply_filters( 'default_feed', 'rss2' );

rss 1.0/ rdf: $default_feed = apply_filters( 'default_feed', 'rdf' );

更改完毕,刷新一下页面即可切换完成。

img

默认的 RSS 其实也没什么问题,只不过目前各类博客对于 RSS 输出的内容有些混乱,使用 Atom 会使 Feed 更加规范。

🔲 ☆

记一次 WordPress 错误(重定向次数过多)

打算把服务器挪到本地来了,使用FRP映射到有公网IP的服务器上。

今天在挪完之后通过 Frp 的 https2http 代理到公网 IP 的服务器上,但是打开域名突然显示重定向次数过多,最初以为是 Frp 的问题,但是检查了一下配置完全没问题,遂怀疑到了WP的头上。


解决方法

遍访了百度,终于找到了答案,将一下代码复制到 wp-config.php 的如下位置即可。

img

将下列代码复制到文件这个位置即可解决问题

代码

1
2
3
$_SERVER['HTTPS'] = 'on';
define('FORCE_SSL_LOGIN', true);
define('FORCE_SSL_ADMIN', true);
🔲 ☆

Docker系列 WordPress系列 m2w 2.6:博客管理的重要转折点

Bensz
Docker系列 WordPress系列 m2w 2.6:博客管理的重要转折点

本博客由AI模型商OhMyGPT强力驱动!如何更快地访问本站?有需要可加电报群获得更多帮助。本博客用什么VPS?创作不易,请支持苯苯!推荐购买本博客的VIP喔,10元/年即可畅享所有VIP专属内容! 概览 本文围绕 前言 展开详细讨论 包含 13 个主要章节内容 分享实践经验和实用技巧 前言 前文回顾:Docker系列 WordPress系列 WordPress上传或更新Markdown的最佳实践-m2w 2 使用2.5版本的小伙伴,升级时记得改为2.6版本的 myblog.py。内容大体上是相似的,但有一丁点区别。还是直接换掉保险 (~ ̄▽ ̄)~ 有什么问题加tg群问哈 小伙伴们都还记得之前我们介绍过的 m2w 吗?就是那个可以将本地 Markdown 文件自动上传或更新到 WordPress 的神奇工具!时隔不久,m2w 迎来了 2.6 版本,这个版本可不是小修小补,而是带来了许多重要 […]

Bensz

❌