博客 (124)

错误 BLAZOR102     The scoped css file was defined but no associated razor component or view was found for it.

错误 BLAZOR106 The JS module file was defined but no associated razor component or view was found for it.

解决方法:将相关文件从项目中排除,再包括到项目中即可正常生成。

若仍报错,备份这些文件,删除并新建文件,复制代码进去尝试生成。

若仍报错,通过注释代码的方式排查问题原因。

xoyozo 2 年前
2,130

首先,禁止网站下所有 .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.html

nginx 仍然运行了 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;)的上方才有效。


附:一键生成 nginx 访问控制 location URI { } 语句工具

xoyozo 3 年前
3,230

将 Windows 更新代理更新到最新版本:从 Microsoft 下载中心手动下载 Windows 更新代理

再次尝试。

如果仍然失败,尝试手动安装这两个更新:KB3020369KB3125574,本人未测试。

xoyozo 3 年前
3,700

iPhone 或安卓上传的照片,可能因横向或纵向拍摄,导致上传后照片显示成 90 度、180 度、270 度角旋转,使用 C# 处理该照片时同样会遇到相同的问题。

解决的方案:

客户端使用 base64 显示图片,可按正常方向显示,且不通过服务端即时显示。关键代码:

$('#file_input').change(function (e) {
    if (e.target.files.length == 0) { return; }
    // file 转换为 base64
    var reader = new FileReader();
    reader.readAsDataURL(e.target.files[0]);
    reader.onload = function (event) {
        $('#myImg').attr('src', event.target.result).css({ width'auto'height'auto' });
    }
});
$('#myImg').on('load'function () {
    console.log('图片加载完成')
});

但 base64 字符串传递到服务端受请求大小限制(一般比直接 POST 文件要小)。所以显示图片的同时应即时使用 POST 方式上传图片(如 jquery.fileupload.js)。

当然如果是在微信中打开网页,使用 JS-SDK 的 wx.chooseImage() 返回的 localId 也可以在 <img /> 中正常显示,然后使用 wx.uploadImage() 上传到微信服务器并获取 serverId,在通过获取临时素材接口取回图片文件。

服务端如果需要处理该图片(缩放、裁切、旋转等),需要先读取照片的拍摄角度,旋正后,再进行处理,相关 C# 代码:

/// <summary>
/// 调整照片的原始拍摄旋转角度
/// </summary>
/// <param name="img"></param>
/// <returns></returns>
private Image ImageRotateFlip(Image img)
{
    foreach (var prop in img.PropertyItems)
    {
        if (prop.Id == 0x112)
        {
            switch (prop.Value[0])
            {
                case 6: img.RotateFlip(RotateFlipType.Rotate90FlipNone); break;
                case 3: img.RotateFlip(RotateFlipType.Rotate180FlipNone); break;
                case 8: img.RotateFlip(RotateFlipType.Rotate270FlipNone); break;
            }
            prop.Value[0] = 1;
        }
    }
    return img;
}
xoyozo 3 年前
3,050

如果你的视图页面(.cshtml)是由另一个视图页面复制而来的,就有可能出现开发调试时正常,发布到服务器后打开报 500 错误。

解决方法是:新建一个 .cshtml 页面,将代码移植到这个文件上,删除原来的页面,更改刚创建的文件名。

你也可以直接修改项目文件将视图页面重新包含到项目中。

xoyozo 3 年前
1,888

本文记录于 2021 年 9 月。



升级前期望(最新正式版)最终选择
操作系统CentOS 6.5Alibaba Cloud Linux 3Alibaba Cloud Linux 3
管理面板lnmp宝塔面板 Linux 版 7.7.0宝塔面板 Linux 版 7.7.0
Web 服务nginx 1.6nginx 1.21nginx 1.21
脚本语言PHP 5.6PHP 8.0PHP 7.4
数据库
RDS MySQL 5.6RDS MySQL 8.0RDS MySQL 5.6
论坛程序
Discuz! X3.2 GBKDiscuz! X3.5 UTF-8(即将发布)Discuz! X3.4 GBK


版本选择原因:

  • Alibaba Cloud Linux 完全兼容 CentOS,相比于 CentOS 较短的生命周期,Alibaba Cloud Linux 3 将于 2029 年 4 月 30 日结束生命周期。

  • Discuz! X3.4 不支持 PHP 8.0,安装时即报错,打开页面时一片空白。

  • MySQL 8.0 和阿里云 RDS 的 MySQL 7.5 不支持 MyISAM,而数据表 pre_common_member_grouppm 和 pre_forum_post 使用联合主键且自动递增字段不是第一主键,使用 InnoDB 引擎创建表时会报“1075 - Incorrect table definition; there can be only one auto column and it must be defined as a key”错误,而擅自更改主键次序会影响业务逻辑。因此,在必须选择阿里云 RDS 的情况下,只能选择 MySQL 5.6。(2023年8月注:查看如何更改为 InnoDB

  • Discuz! X3.5 正式版尚未发布(截止发稿),即便发布,插件也可能不能得到及时更新。相比之下,X3.4 首个版本发布距今已有 4 年,相关第三方插件已经非常成熟。


完整升级步骤:

  1. 备份原网站程序、RDS 数据库;

  2. 购买新的 ECS、RDS,挂载磁盘,安装云监控;

  3. 迁移(或还原)数据库到新的 RDS;

  4. 安装宝塔面板并配置;

  5. 安装 nginx 及 PHP;

  6. 创建网站、配置 SSL、伪静态、防盗链、可写目录禁执行等(.conf);

  7. 配置 hosts;

  8. 上传原网站程序到新的站点目录下;

  9. Discuz! X 升级文档升级 X3.2 至 X3.4;详情见下文 ↓;

  10. 配置 OSS、Redis、更新缓存等;

  11. 测试论坛基本功能是否正常;检查附件是否正常显示;全面检查控制台配置;

  12. 逐个开启插件并检查兼容性;

  13. 按二开备忘录逐个按需进行二开;

  14. 逐个修改调用论坛接口的项目及直接调用论坛数据库的项目;

  15. 调试 MAGAPP 接口;

  16. 尝试强制 https 访问;

  17. 将以上所有修改后的程序保留备份;发布升级公告并关闭论坛;重复以上步骤;修改域名解析;开启论坛;

  18. 配置 IP 封禁、定时器、日志、自动备份、配置其它 ECS 的 hosts 等;

  19. 查看搜索引擎中收录的地址,是否有无法访问的情况;

  20. 尝试将历史遗留的本地附件全部转移到 OSS;

  21. 这篇文章,可能有其它需要配置的地方。


Discuz! X 升级步骤及注意点:

  • 升级前务必先修改 ./config/ 目录下的数据库/缓存连接信息,以防出现新站连接老库的情况;

  • 官方文档进行升级;

  • 【问题】运行到 ./install/update.php?step=data&op=notification 时白屏。

    【排查】尝试切换到 PHP 5.6 后成功(但该版本过于陈旧不能使用);尝试升级 CPU 和内存 PHP 7.4 上升级仍不成功。

    【原因】DB::result_first() 方法不对 SQL 语句追加“limit 1”,而是 SELECT 所有记录后在 PHP 端取第一条数据;

    【解决】打开文件 update.php,查找 elseif($_GET['op'] == 'notification'),该节点的功能是在表 home_notification 中查找 category <= 0 的数据并修复它,如果数据库中所有 category 都大于 0,直接注释其内部 if 代码段继续升级即可(或改为 if(false && ...))。

  • 【问题】发布主题遇到错误:(1062) Duplicate entry '*' for key 'pid'

    【原因】forum_post 中的 pid 不是自动增长的,而是由表 forum_post_tableid 中自动增长的 pid 生成的。如果生成的 pid 值已在 forum_post 表中存在,则会出现此错误。

    【解决】迁移数据库时应关闭论坛,以防止 forum_post 表有新数据插入。

  • 【问题】打开帖子页面 ./thread-***-1-1.html 显示 404 Not Found,而 ./forum.php?mod=viewthread&tid=*** 可以正常打开

    【原因】未配置伪静态(可在宝塔面板中选择)

  • 【问题】打开 UCenter 时报错:UCenter info: MySQL Query Error SQL:SELECT value FROM [Table]vars WHERE name='noteexists'

    【解决】打开文件 ./uc_server/data/config.inc.php 配置数据库连接

  • 【问题】打开登录 UCenter 后一片空白

    【解决】将目录 ./uc_server/data/ 设为可写

  • 需要将原来安装的插件文件移回 ./source/plugin/ 目录,并设置可写;

  • 界面-表情管理,界面-编辑器设置-Discuz!代码


后续 Discuz! X3.4 R 小版本升级注意事项:

  1. 确认插件是否支持新版本(如短信通)

  2. 先创建一个新网站测试二开代码

  3. 保留 /config/、/data/、/uc_client/data/、/uc_server/data/、/source/plugin/,其它移入 old

  4. 上传文件

  5. 移回其它需要的文件,如:

  6. -- 勋章/loading/logo/nv 等:/static/image/common/

  7. -- 表情:/static/image/smiley/

  8. -- 水印:/static/image/common/watermark.*

  9. -- 风格:/template/default/style/t2/nv.png 等

  10. -- 默认头像:/uc_server/images/noavatar_***.gif

  11. -- 根目录 favicon.ico 等

  12. -- 及其它非 DZ 文件

  13. 再次检查可写目录的写入权限和禁止运行 PHP 效果。

xoyozo 3 年前
4,461

1075 - Incorrect table definition; there can be only one auto column and it must be defined as a key

在 MyISAM 转 InnoDB 时出现。

原因:这个表有联合主键,且自增的字段不是第一个主键。

解决方法一,取消自增字段的自动递增,改为在程序中实现;

解决方法二,单独给自增字段单独添加一个索引。


以 Disucz! X3.4 为例,方法一改程序代码显然困难比较大,所以选择方法二。

表 pre_forum_post 中,tid 为第1主键,position 为第2主键且自增。

tid 表示主题,position 表示该帖在该主题中的位置(类似于楼层的概念)。

所以在原来 MyISAM 中可以方便地实现 position 在各自的主题下自增。


给 position 单独添加索引后可以将引擎改为 InnoDB,但是 position 在全表范围内自增了。

也就是说,如果发布一个新主题,那么这个主题帖的 position 就不是1,而是整个数据库中最大的 position 再加 1。

虽然不影响页面中帖子的排序和楼层号显示,但不知道会不会有其它问题,所以最好把它改过来。


给表 pre_forum_post 添加一个触发器,在插入前(BEFORE INSERT)

BEGIN
    DECLARE max_position INT;
    
    SELECT MAX(position) INTO max_position FROM pre_forum_post WHERE tid = NEW.tid;
    
    IF max_position IS NULL THEN
        SET max_position = 0;
    END IF;
    
    SET NEW.position = max_position + 1;
END

在上面触发器的定义中,NEW 指即将要插件的一条记录,在新插入的帖子所在主题中寻找最大的 position 赋值给一个 INT 变量,如果找不到就赋值 0,然后 +1 赋值给新的 position。

这样就实现了与原来相同的效果。


用同样的方法给表 pre_common_member_grouppm 添加触发器。

如果帖子有分表,给每个分表添加触发器,下次有新的分表也要记得添加。

xoyozo 3 年前
2,515

未能找到元数据文件

可能是代码中使用了:

#if !DEBUG
#endif

而其中包含了在 Release 模式下会出现异常的代码。

xoyozo 4 年前
2,385

严重性代码说明项目文件禁止显示状态

错误CS0121以下方法或属性之间的调用具有二义性:“System.Linq.Queryable.Where<TSource>(System.Linq.IQueryable<TSource>, System.Linq.Expressions.Expression<System.Func<TSource, bool>>)”和“System.Linq.AsyncEnumerable.Where<TSource>(System.Collections.Generic.IAsyncEnumerable<TSource>, System.Func<TSource, bool>)”活动


The call is ambiguous between the following methods or properties.

引用的扩展或其版本有冲突,暂时在查找的表后面加上“AsQueryable()”解决。

xoyozo 4 年前
6,596

天地图https://map.tianditu.gov.cn/

开放平台:http://lbs.tianditu.gov.cn/

控制台:https://console.tianditu.gov.cn/

版本 类参考 代码示例
JavaScript API 4.0 类参考 代码示例
JavaScript API 4.0 开源库 资源引用、类参考及示例

若不显示地图,请添加域名白名单。

坐标系:CGCS 2000(国家大地坐标系)


高德地图https://www.amap.com/

开放平台:https://lbs.amap.com/

控制台:https://console.amap.com/

版本 参考手册 示例中心
JS API v2 参考手册 示例中心
JS API v1 参考手册 示例中心

更多:坐标获取

坐标系:GCJ-02(火星坐标、国测局坐标系)


百度地图https://map.baidu.com/

开放平台:http://lbsyun.baidu.com/

控制台:http://lbsyun.baidu.com/apiconsole/center

版本 类参考 示例DEMO
JavaScript API GL 类参考 示例DEMO
JavaScript API v3.0 类参考 示例DEMO

更多:拾取坐标系统

坐标系:BD-09(百度坐标)


腾讯地图https://map.qq.com/

PC端于2022年11月11日停止服务

开放平台(腾讯位置服务):https://lbs.qq.com/

控制台:https://lbs.qq.com/dev/console

版本 参考手册 示例
JavaScript API GL 参考手册 示例

坐标系:GCJ-02(火星坐标、国测局坐标系)


附:常见地图经纬度坐标系及转换

xoyozo 4 年前
8,517