403766640 发布的文章

前言

又到了废话的时候,前些年刚上高中的时候,想要建站,一开始买的星辰云的虚拟主机,后来换成了云服务器。第一次用云服务器,买到手才发现和虚拟主机完全不一样,他没有控制面板?

当时纯小白,问别人也没人理,后来第一个月的机器压根没用到,白白浪费了。再后来才知道了宝塔面板,宝塔也可以说是我的启蒙面板了

教程开始

首先你要拥有一台服务器,去哪里买无所谓,练手的话小厂便宜,大型业务的话大厂稳定。如果你愿意的话可以走我的推广链接,就当赞助我了。

点我购买

值得注意的是,新手不推荐买大陆地区的服务器,因为要备案,很麻烦

系统选择

购买服务器时会让选择操作系统,按照下述顺序选择,排名越靠前的,与宝塔面板兼容性越好

Debian12、Ubuntu22、Centos9、OpenCloud9、TencentOS Server4,AlibabaCloud 3、麒麟,统信,欧拉等Linux系统

这里使用Debian12举例

连接服务器

在控制台查看服务器的IP、用户名、密码、端口

记下这些信息后,使用SSH工具连接服务器,这里推荐使用堡塔多机管理

填写相关信息后保存并打开终端

安装宝塔

输入安装命令:

if [ -f /usr/bin/curl ];then curl -sSO https://download.bt.cn/install/install_latest.sh;else wget -O install_latest.sh https://download.bt.cn/install/install_latest.sh;fi;bash install_latest.sh ssl251210

执行后会出现确认提示,输入y并回车,接下来等着就行

安装成功

出现如下文字即为安装成功,将面板信息复制保存

安装必备组件

访问面板地址并登录,按照提示绑定账号

安装服务器必备组件,按需选择

如果你是学习使用,可以选择快速安装,如果是正式上线的运行环境,建议选择编译安装。

面板效果

前言

去年alist暴雷之后,就换成了社区维护的openlist,用了很久了,今天做一期教程,也避免后来者再去翻阅文档

安装教程

只介绍两种方法,宝塔docker一键安装和脚本安装。

安装宝塔面板的过程查看之前的文章

https://blog.chario.cn/wiki/27.html

宝塔docker

在后台左侧菜单栏点击docker,右侧点击立即安装。安装方式默认即可,如遇到安装失败,可尝试二进制安装

    安装完成后在docker商店的分类找到储存/网盘,下滑找到openlist,点击安装。

    在弹出的窗口填写需要的信息,没有域名的话就空着,CPU和内存限制根据实际情况调整。都填好之后点击确定,等待安装完成

    查看日志,安装好后点击已安装刷新一下就能看到了点击详情,可以查看后台的账号,然后复制设置openlist密码的命令到终端


    访问你设置的域名即可看到页面。没置域名的就访问你的IP:程序端口,如:127.0.0.1:15244

    登录之后会提醒你去设置存储,点击按钮进入设置页面

    openlist支持数十种储存方式,你可以任意选择

      一键安装脚本

      安装要求

      • 使用 systemd 的 Linux 系统
      • Root 权限
      • 已安装 curl, tar
      • 下载页面中列出的架构(openlist支持大多数架构,这点无需担心)

      执行安装脚本

      在确定你的系统支持后,执行下述命令:

      curl -fsSL https://res.oplist.org/script/v4.sh > install-openlist-v4.sh && sudo bash install-openlist-v4.sh

      在底部输入选项,因为我们要安装,所以填1,然后回车

      接下来会要求填写加速代理地址,可填可不填,我填的是https://gh-proxy.com/,你也可以填https://ghproxy.net/

      回车之后等待下载,下载的快慢取决你服务器的配置

      安装完成后会显示你的程序信息,务必截图/复制保存

      后续在终端输入openlist即可完成更新、卸载、重启等操作

      反向代理

      命令行安装的用户需要设置反向代理才能通过域名访问

      新建站点

      修改站点设置

      删除面板默认代码

      添加反向代理

        如需申请SSL证书,可先在SSL选项中申请证书,然后在设置反向代理。或者设置反向代理之后,关闭反向代理功能,申请SSL证书后再次开启代理。

        前言

        早在很久之前就开始建站,当时用的小鸡,所以存不了那么多数据,想到了云储存,但看了一圈价格都好贵。就在这时,我发现了一家可以免费提供云储存的大厂——又拍云

        52bc1770636882.png

        又拍云是我的第一个云储存,也是我截至今日使用最久的云储存。

        我相信它绝对是新站长值得一试的服务

        什么是云储存

        云存储就像是一个存放在互联网上的巨大、虚拟的U盘或硬盘。它让您无需购买和维护实体硬件,就能通过网络随时随地存储、管理和访问自己的数据。这些数据被安全地保存在由专业服务商运营的庞大服务器集群中,具备高可靠性、无限扩展性和成本效益。

        更多请参考云储存 | 百度百科

        为什么选又拍云

        又拍云联盟

        这就要提起又拍云有一个名为「又拍云联盟」的活动。

        即在页脚挂上又拍云的 LOGO(就像我的资源博客:知喜博客一样),便会每月赠送 10 GB 存储空间和 15 GB 流量。 而且直接折算为等额的代金券,按年发放,这相比其他的(白嫖)方案赠送额度更多,且更为方便。

        譬如倘若某一个月流量较少,某一个月流量较多,都可以共享这张代金券。 而若是按照腾讯云按月 10 GB 的制度,某个月没有用到 10 GB,就显得亏了,某个月不小心用超了,却又需要多付上一些钱财。

        操作流程

        申请

        访问又拍云官网[button color="info" icon="" url="https://console.upyun.com/register/?invite=bia88Lpsi" type=""]点我访问又拍云[/button],注册后在首页滑到底部找到又拍云联盟

        82a51770636913.png

        将下方代码添加到你的网站页脚

        <span>本网站由 <a href="https://www.upyun.com/?utm_source=lianmeng&utm_medium=referral"  target="_blank"><img src="https://s41.ax1x.com/2026/01/16/pZs14UI.png" width="53" height="23" style="fill: currentColor;"/></a> 提供 CDN 加速/云存储服务</span>

        然后点击申请,填写信息

        a8f21770636932.png

        最后等待审核就可以了

        其他

        说了一堆,但他肯定也有缺点。

        毕竟从体量上来说,不能和腾讯云、阿里云这些国内大厂商相比。因此部分程序不支持使用又拍云储存。

        还有一点就是我并没有找到设置超额自动停止服务的功能,当使用费用超过我的代金券时,它会变为欠款,而不是自动停止服务。

        当然对于访问量不大的站长来说,免费这一点就可以掩盖他的这点小小的缺点了

        在此插播一则广告~https://console.upyun.com/register/?invite=bia88Lpsi

        然后这里是咱的 又拍云返利链接,从这里注册并消费我会吃到回扣!(当然其实又拍云联盟赠送的量对于个人来说就基本够用了。赠送的额度不够用的时候,说明有很多人在关注你啦,就去找又拍云合作吧!)

        又拍云大使介绍

        主题标题居中

        打开后台-更改外观-设置外观-开发者设置-复制代码粘贴至自定义CSS即可

        /*主题标题居中*/
        header.bg-light.lter.wrapper-md {
          text-align: center;
        }

        handsome 原生入站提示

        打开后台-更改外观-设置外观-开发者设置-复制代码粘贴至自定义输出body尾部代码即可

        <script>
        function kaygb_referrer(){
        var kaygb_referrer = document.referrer;
        if  (kaygb_referrer != ""){
        return "感谢您的访问! 您来自:<br>" + document.referrer;
        }else{
        return "";
        }}
        $.message({
            message: "为了网站的正常运行,请不要使用广告屏蔽插件,谢谢!<br >" + kaygb_referrer(),
            title: "网站加载完成",
            type: "success",
            autoHide: !1,
            time: "3000"
        })
        </script>

        评论一键赞、踩、打卡

        打开后台-更改外观-设置外观-开发者设置-复制代码粘贴至自定义JavaScript即可

        <!--评论 打卡、赞、踩 功能-->
        window.SIMPALED = {}; // 创建全局对象 SIMPALED,用于存放编辑器功能
        ​
        // 定义一个函数 a,用于在文本框中插入文字
        function a(a, b, c) {
          if (document.selection) {
            a.focus();
            sel = document.selection.createRange();
            c ? (sel.text = b + sel.text + c) : (sel.text = b);
            a.focus();
          } else if (a.selectionStart || "0" == a.selectionStart) {
            var l = a.selectionStart;
            var m = a.selectionEnd;
            var n = m;
            c
              ? (a.value =
                  a.value.substring(0, l) + b + a.value.substring(l, m) + c + a.value.substring(m, a.value.length))
              : (a.value = a.value.substring(0, l) + b + a.value.substring(m, a.value.length));
            c ? (n += b.length + c.length) : (n += b.length - m + l);
            l == m && c && (n -= c.length);
            a.focus();
            a.selectionStart = n;
            a.selectionEnd = n;
          } else {
            a.value += b + c;
            a.focus();
          }
        }
        ​
        window.SIMPALED.Editor = {
          daka: function() {
            var b = new Date().toLocaleTimeString();
            var c = document.getElementById("comment") || 0;
            a(c, "滴!学生卡!打卡时间:" + b, ",请上车的乘客系好安全带~");
        ​
            // 将光标移到文本最后
            if (c.setSelectionRange) {
              var len = c.value.length;
              c.setSelectionRange(len, len);
              c.focus();
            } else if (c.createTextRange) {
              var range = c.createTextRange();
              range.collapse(false);
              range.select();
              c.focus();
            }
          },
        ​
          zan: function() {
            var c = document.getElementById("comment") || 0;
            var yuluResponses = [
              " 这篇文章展现了作者深邃的思想和独特的观点,令人赞叹不已。 ",
              " 文章中的优美语言和精彩描写让人感受到一种心灵的震撼和触动,实在值得赞美。 ",
              " 作者以敏锐的洞察力和真挚的情感,将文字融为一体,这种写作技巧令人赞赏。 ",
              " 这篇文章展现了作者的才华和学识,无不让人对其赞美有加。 ",
              " 文章中的感人故事和深刻的寓意令人深深地感动和赞叹。  ",
              " 作者的文字流畅而富有节奏感,令人为之倾倒,实在是一篇令人赞美的佳作。 ",
              " 文章中的深邃思考和清晰逻辑令人对作者的才华赞赏不已。 ",
              " 这篇文章的独到见解和新颖观点,让人对作者的创意赞美有加。 ",
              " 作者运用生动的比喻和细腻的描写,让读者仿佛身临其境,实在是一种令人赞美的写作艺术。 ",
              " 这篇文章的深情笔触和真挚感受让人深深感叹,实在是一篇值得赞美的美文。 ",
            ];
        ​
            var randomIndex = Math.floor(Math.random() * yuluResponses.length);
            var randomResponse = yuluResponses[randomIndex];
            a(c, randomResponse);
          },
        ​
          cai: function() {
            var c = document.getElementById("comment") || 0;
            var yuluResponses = [
              " 我是来替大家批评博主的,我是来批评的,这篇文章的结构有点混乱,需要更好地组织和展开内容。博主多多像我学习啊! ",
              " 我是来替大家批评博主的,作者的表达能力有待提高,有些地方表述不够清晰,读者可能会感到困惑。博主多多像我学习啊! ",
              " 我是来替大家批评博主的,文章的语法错误较多,建议仔细检查并进行修改。博主多多像我学习啊! ",
              " 我是来替大家批评博主的,内容有些空洞,需要更多具体的例子或细节来支撑观点。博主多多像我学习啊! ",
              " 我是来替大家批评博主的,文章缺乏逻辑,有些段落之间的衔接不够自然。博主多多像我学习啊! ",
              " 我是来替大家批评博主的,作者的观点没有充分论证,需要更多的证据和理由来支持主张。博主多多像我学习啊! ",
              " 我是来替大家批评博主的,文章中出现了一些拼写错误和用词不当的情况,建议进行仔细校对。博主多多像我学习啊! ",
              " 我是来替大家批评博主的,语言表达过于简单,可以尝试使用更丰富的词汇和句式来提升文章质量。博主多多像我学习啊! ",
              " 我是来替大家批评博主的,这篇文章的主题不够突出,需要更好地明确中心思想。博主多多像我学习啊! ",
              " 我是来替大家批评博主的,文章缺乏吸引人的开头,建议引入更有趣的故事或引语来吸引读者注意。博主多多像我学习啊! ",
            ];
        ​
            var randomIndex = Math.floor(Math.random() * yuluResponses.length);
            var randomResponse = yuluResponses[randomIndex];
            a(c, randomResponse);
          },
        ​
          yulu: function() {
            var c = document.getElementById("comment") || 0;
            var yuluResponses = [
              " 有你在的日子才是我的日常。 ",
              " 夹在我女友与前女友与青梅竹马间的果然是修罗场! ",
              " 既然如此,就再努力一次吧。别在这里愁眉不展,也不要再自欺欺人,重新来过! ",
              " 比自己,比梦想更重要的东西永远都存在着... ",
              " 嘛,那又怎么样呢? ",
              " 自身不先改变的话,一切都不会改变。 ",
              " 比起有一百个朋友,不如有个比一百人还要重要的真心朋友。 ",
              " 我有在反省,但我不后悔。 ",
              " 要超越过去与悲伤,用坚强和笑容去开拓明天。 ",
              " 男人许下的诺言就一定要遵守。 ",
              " 没有回忆就去创造回忆,没有道路就去开辟道路。 ",
              " 我敬你是条汉子! ",
              " 不相信自己的人,连努力的价值都没有。 ",
              " 微风摇曳着窗帘,夕阳斜射入教室,在那里鼓起勇气告白的少年。即使现在也能清晰地回想起她的声音「当朋友,不行吗?」 ",
              " 就算是沉落地面的太阳,只要夜晚过了一定会再度升起,不管有什么痛苦或难过的事,跟今天截然不同的明天也一定会到来。 ",
              " 我的腿让我停下,可是心却不允许我那么做。 ",
              " 生活就像超级女生,走到最后的都是纯爷们。 ",
              " 我要拼,装上假牙也要拼! ",
              " 想要成为无论多么悲伤的时候,也能够漂亮微笑的人吧。 ",
              " 人们只是用好人来称呼对自己有用的人而以,不存在对所有人都有用的人。 ",
              " 烈焰中舞动的火花,将赐予邪恶异性交往以天罚。 ",
              " 无论乌云有多浓厚,星星也一定还在,只是暂时看不到了而已。 ",
              " 不相信人咬不到肚脐的,咬破肚脐去死如何? ",
              " 人一生会遇到约万人,两个人相爱的概率是.。所以你不爱我,我不怪你。 ",
              " 不管看到什么样的过去,都请不要迷失自己,不管你变成什么样子,我都是你的同伴。 ",
              " 心,可是很重的。 ",
              " 我爱上的人,称我为怪叔叔 ",
              " 慕君之心,至死方休。 ",
              " 虚伪的眼泪,会伤害别人,虚伪的笑容,会伤害自己。 ",
              " 若隐若现才是艺术! ",
              " 生我何用?不能欢笑。灭我何用?不减狂骄。 ",
              " 就是因为你不好,才要留在你身边,给你幸福。 ",
              " 呐,我们好像是,被宇宙和地球拆散的恋人似的。 ",
              " 你会梦游,我会磨牙,我们晚上一起去吓人吧! ",
              " 或许只需一滴露水,便能守护这绽放的花朵。 ",
              " 自己永远是孤单的,但你可以让其他人变得不孤单。 ",
              " 和哥哥的便当比起来夜空的薯片就像大便一样!只会给我大便的大便夜空是笨蛋~笨蛋~ ",
              " 我手中的魔法,是守护挚爱的力量,是坚定这个信念所必须的力量,我一定会拯救你的,无论在何时、何地。 ",
              " 要改变别人的心真是件很难办的事,不过改变自己要容易一点。 ",
              " 风筝的线你随时可以放开,只是别盼望我会回来。 ",
              " 与你的生命等价的东西,这个世界上根本没有。 ",
              " 君子可寓意于物,但不可留意于物。 ",
              " 最好的感觉,是有人懂你的欲言又止。 ",
              " 看似美好的东西,往往藏着陷阱。 ",
              " 爱,其实很简单,困难的是去接受它。 ",
              " 喜欢大胸只是本能,喜欢贫乳才是审美。 ",
              " 二次元什么的我本来是不感冒的,直到我的膝盖中了一箭。 ",
              " 努力是不会背叛自己的,虽然梦想有时会背叛自己。 ",
              " 面对就好,去经历就好。 ",
              " 我从小就害怕虫子 ",
              " 做不到的话,不过就是一死 。但是,赢了就能活下去,要是不战斗就赢不了。 ",
              " 既然认准这条路,何必去打听要走多久。 ",
              " 研表究明,汉字的序顺并不定一能影阅响读,比如当你看完这句话后,才发这现里的字全是都乱的。 ",
              " 少年心意,一如明月松间的青石流水,那些年里看到了,却不懂。 ",
              " 明明只是活着,哀伤却无处不在⋯⋯ ",
              " 少罗嗦,你还不如虫子呢! ",
              " 天空是连着的,如果我们也能各自发光的话,无论距离有多远,都能看到彼此努力的身影。 ",
              " 别人恋爱不成功,你连暗恋都不成功! ",
            ];
        ​
            var randomIndex = Math.floor(Math.random() * yuluResponses.length);
            var randomResponse = yuluResponses[randomIndex];
            a(c, randomResponse);
          },
        };

        打开Handsome主题目录下的 component/comments.php文件,找到并删除如下内容:

        修改成如下代码:

        <textarea id="comment" class="textarea form-control OwO-textarea" name="text" rows="5" placeholder="<?php _me("说点什么吧……") ?>" οnkeydοwn="if(event.ctrlKey&&event.keyCode==13){document.getElementById('submit').click();return false};"><?php $this->remember('text'); ?></textarea>
        <div class="OwO" style="display: inline;"></div>
        <div class="OwO" title="打卡" style="display: inline;" onclick="javascript:SIMPALED.Editor.daka();"><div class="OwO-logo"><span class="smile-icons"><i class="iconfont icon-daohanglan-01"></i></span><span class="OwOlogotext">打卡</span></div></div>
        <div class="OwO" title="语录" style="display: inline;" onclick="javascript:SIMPALED.Editor.yulu();"><div class="OwO-logo"><i class="fontello-pencil"></i><span class="OwOlogotext">语录</span></div></div>
        <div class="OwO" title="赞" style="display: inline;" onclick="javascript:SIMPALED.Editor.zan();"><div class="OwO-logo"><i class="glyphicon glyphicon-thumbs-up"></i><span class="OwOlogotext"></span></div></div>
        <div class="OwO" title="踩" style="display: inline;" onclick="javascript:SIMPALED.Editor.cai();"><div class="OwO-logo"><i class="glyphicon glyphicon-thumbs-down"></i><span class="OwOlogotext"></span></div></div>

        时光机头像圆形

        打开后台-更改外观-设置外观-开发者设置-复制代码粘贴至自定义CSS即可

        /* 时光机圆形头像 */
        .img-square {border-radius: 50%;}
        .list-group-item .thumb-sm .img-square {border-radius: 5px;}

        logo 扫光

        打开后台-更改外观-设置外观-开发者设置-复制代码粘贴至自定义CSS即可

        /* logo 扫光开始 */
        .navbar-brand{position:relative;overflow:hidden;margin: 0px 0 0 0px;}.navbar-brand:before{content:""; position: absolute; left: -665px; top: -460px; width: 200px; height: 15px; background-color: rgba(255,255,255,.5); -webkit-transform: rotate(-45deg); -moz-transform: rotate(-45deg); -ms-transform: rotate(-45deg); -o-transform: rotate(-45deg); transform: rotate(-45deg); -webkit-animation: searchLights 6s ease-in 0s infinite; -o-animation: searchLights 6s ease-in 0s infinite; animation: searchLights 6s ease-in 0s infinite;}@-moz-keyframes searchLights{50%{left: -100px; top: 0;} 65%{left: 120px; top: 100px;}}@keyframes searchLights{40%{left: -100px; top: 0;} 60%{left: 120px; top: 100px;} 80%{left: -100px; top: 0px;}}
        /*logo 扫光结束*/

        复制版权提示

        打开后台-更改外观-设置外观-开发者设置-复制代码粘贴至自定义JavaScript即可

        /* 复制成功提示代码开始 */
        kaygb_copy();
        function kaygb_copy() {
            $(document).ready(function () {
                $("body").bind('copy', function (e) {
                    hellolayer();
                });
            });
            var sitesurl = window.location.href;
            function hellolayer() {
                $.message({
                    message: "尊重原创,转载请注明出处!<br> 本文作者:XXX<br>原文链接:" + sitesurl,
                    title: "复制成功",
                    type: "warning",
                    autoHide: false,
                    time: "3000"
                });
            }
        }
        /* 复制成功提示代码结束 */

        彩色标签云及右栏数字

        打开后台-更改外观-设置外观-开发者设置-复制代码粘贴至自定义JavaScript即可

        /*彩色标签云代码开始*/
        let tags = document.querySelectorAll("#tag_cloud-2 a");
        let infos = document.querySelectorAll(".badge");
        let colorArr = ["#428BCA", "#AEDCAE", "#ECA9A7", "#DA99FF", "#FFB380", "#D9B999"];
        tags.forEach(tag => {
        tagsColor = colorArr[Math.floor(Math.random() * colorArr.length)];
        tag.style.backgroundColor = tagsColor;
        });
        infos.forEach(info => {
        infosColor = colorArr[Math.floor(Math.random() * colorArr.length)];
        info.style.backgroundColor = infosColor;
        });
        /*彩色标签云代码结束*/

        响应时间和访客总数

        将以下代码放到/usr/themes/handsome/function.php的最下面

        /*访问总量代码开始*/
        function theAllViews(){
        $db = Typecho_Db::get();
            $row = $db->fetchAll('SELECT SUM(VIEWS) FROM `typecho_contents`');
                echo number_format($row[0]['SUM(VIEWS)']);
        }
        /*访问总量代码结束*/
        /*响应时间代码开始*/
        function timer_start() {
        global $timestart;
        $mtime = explode( ' ', microtime() );
        $timestart = $mtime[1] + $mtime[0];
        return true;
        }
        timer_start();
        function timer_stop( $display = 0, $precision = 3  ) {
        global $timestart, $timeend;
        $mtime = explode( ' ', microtime() );
        $timeend = $mtime[1] + $mtime[0];
        $timetotal = number_format( $timeend - $timestart, $precision  );
        $r = $timetotal < 1 ? $timetotal * 1000 . " ms" : $timetotal . " s";
        if ( $display ) {
        echo $r;
        }
        return $r;
        }
        /*响应时间代码结束*/

        然后将以下代码放到/usr/themes/handsome/component/sidebar.php内,找到博客信息添加即可

        <!--访客总数代码开始-->
        <li class="list-group-item text-second"> <span class="blog-info-icons"> <i data-feather="users"></i></span>
        <span class="badge pull-right"><?php echo theAllViews();?></span><?php _me("访客总数") ?></li>
        <!--访客总数代码结束-->
        
        <!--响应耗时代码开始-->
        <li class="list-group-item text-second"> <span class="blog-info-icons"> <i data-feather="refresh-ccw"></i></span>
        <span class="badge pull-right"><?php echo timer_stop();?></span><?php _me("响应耗时") ?></li>
        <!--响应耗时代码结束-->

        全站字数统计

        将以下代码放到/usr/themes/handsome/component/sidebar.php的开头

        <?php
        //字数统计
        function allOfCharacters() {
        $chars = 0;
            $db = Typecho_Db::get();
        $select = $db ->select('text')->from('table.contents');
        $rows = $db->fetchAll($select);
            foreach ($rows as $row) { $chars += mb_strlen(trim($row['text']), 'UTF-8'); }
            $unit = '';
        if($chars >= 10000)     { $chars /= 10000; $unit = '万'; }
            else if($chars >= 1000) { $chars /= 1000;  $unit = '千'; }
        $out = sprintf('%.2lf %s',$chars, $unit);
            return $out;
        }
        ?>

        然后将以下代码放到/usr/themes/handsome/component/sidebar.php内,加到合适的位置

        <!--全站字数开始-->
        <li class="list-group-item text-second"><span class="blog-info-icons"><i data-feather="edit-2"></i></span>
        <span class="badge pull-right"><?php echo allOfCharacters(); ?></span><?php _me("全站字数") ?></li>
        <!--全站字数结束-->

        版权提示

        在主题文件post.php内,文章内容下方加上下面的代码

        <div style="padding: 10px;background: rgba(220, 220, 220, 0.22);font-size: 13px;border-left: 3px solid;text-align: left;">
        <span>本文作者:<a href="<?php $this->author->permalink(); ?>" rel="author"> <?php $this->author(); ?></a></span>
        <span>文章标题:<a href="<?php $this->permalink() ?>"><?php $this->title() ?></a><br></span>
        <span>本文地址:<a href="<?php $this->permalink() ?>"><?php $this->permalink() ?></a><br></span>
        <span>版权说明:若无注明,本文皆<a href="<?php $this->options->rootUrl(); ?>" target="_blank" data-original-title="<?php $this->options->title() ?>"><?php $this->options->title() ?></a>原创,转载请保留文章出处。</span>
        </div>

        总结

        通过以上美化方案,你可以让你的 Handsome 主题博客更加个性化和美观。这些功能大多是我自己也在用的。你可以参考截图和本站实际效果,根据自己的需求选择性地使用这些功能。 如果你在使用过程中遇到任何问题,欢迎在评论区留言讨论。同时,也欢迎你分享自己的美化心得,让我们一起打造更好的博客!

        本文转自https://blog.ybyq.wang/archives/325.html,感谢大佬的分享,转载仅做存档,侵权删除

        背景说明

        这个版本和之前的做了以下升级: 1.新增了缓存命中率系统信息操作系统连接类型当前域名的信息显示 2.添加了对应信息项的Awesome图标 3.固定了标签颜色,使其不受插件标签颜色的影响, 4.优化了性能并增加了对Apache的适配。 5.保留了在长亭雷池WAF或宝塔WAF保护下IP的真实性

        功能特点

        • 实时监控服务器CPU、内存、磁盘使用率
        • 显示服务器运行时间、IO和网络状态
        • 准确获取访客IP、地理位置、设备和浏览器信息
        • 全面支持电信、联通、移动等各类网络环境
        • 兼容Linux系统(CentOS Stream 9、Ubuntu 22.04、Debian 10.2等)
        • 环境是Linux系统PHP8.0(7.4以上即可),typecho1.2.1

        实现步骤

        1. 安装必要的系统工具(可选)

        首先,确保系统安装了必要的工具:

        apt-get update
        apt-get install -y procps net-tools sysstat

        2. 修改 headnav.php 文件

        文件位置:usr/themes/handsome/component/headnav.php

        在找到如下代码段:

        <!-- statitic info-->
        <?php
        if (@Utils::getExpertValue("show_static",true) !== false): ?>
        <ul class="nav navbar-nav hidden-sm">
        
            <!-- 在此追加代码 -->
        
            <li class="dropdown pos-stc">

        添加代码:

        [zd-plane title="折叠标题" open="0"]

        <!-- 引入Font Awesome图标库 -->
                <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
                <li class="dropdown pos-stc" id="StateDataPos">
                    <a id="StateData" href="#" data-toggle="dropdown" class="dropdown-toggle feathericons dropdown-toggle">
                        <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-activity">
                            <polyline points="22 12 18 12 15 21 9 3 6 12 2 12"></polyline>
                        </svg>
                        <span class="caret"></span>
                    </a>
                    <div class="dropdown-menu wrapper w-full bg-white">
                        <div class="row">
                            <div class="col-sm-4 b-l b-light">
                                <div class="m-t-xs m-b-xs font-bold">运行状态</div>
                                <div class="">
                                    <span class="pull-right text-danger" id="cpu">
                                        <i class="fas fa-spinner fa-spin" aria-hidden="true"></i>
                                    </span>
                                    <span><i class="fas fa-microchip fa-fw" aria-hidden="true"></i> CPU占用
                                        <span class="badge badge-sm bg-dark">8核心</span>
                                    </span>
                                </div>
                                <div class="progress progress-xs m-t-sm bg-default">
                                    <div id="cpu_css" class="progress-bar bg-danger" data-toggle="tooltip" style="width: 100%"></div>
                                </div>
                                <div class="">
                                    <span class="pull-right text-danger" id="memory">
                                        <i class="fas fa-spinner fa-spin" aria-hidden="true"></i>
                                    </span>
                                    <span><i class="fas fa-memory fa-fw" aria-hidden="true"></i> 占用内存
                                        <span class="badge badge-sm bg-dark" id="memory_data">
                                            <i class="fas fa-spinner fa-spin" aria-hidden="true"></i>
                                        </span>
                                    </span>
                                </div>
                                <div class="progress progress-xs m-t-sm bg-default">
                                    <div id="memory_css" class="progress-bar bg-danger" data-toggle="tooltip" style="width: 100%"></div>
                                </div>
                                <div class="">
                                    <span class="pull-right text-danger" id="disk">
                                        <i class="fas fa-spinner fa-spin" aria-hidden="true"></i>
                                    </span>
                                    <span><i class="fas fa-hdd fa-fw" aria-hidden="true"></i> 磁盘占用
                                        <span class="badge badge-sm bg-dark" id="disk_data">
                                            <i class="fas fa-spinner fa-spin" aria-hidden="true"></i>
                                        </span>
                                    </span>
                                </div>
                                <div class="progress progress-xs m-t-sm bg-default">
                                    <div id="disk_css" class="progress-bar bg-danger" data-toggle="tooltip" style="width: 100%"></div>
                                </div>
                                <div class="">
                                    <span class="pull-right text-danger" id="memCached">
                                        <i class="fas fa-spinner fa-spin" aria-hidden="true"></i>
                                    </span>
                                    <span><i class="fas fa-database fa-fw" aria-hidden="true"></i> 内存缓存
                                        <span class="badge badge-sm bg-dark" id="memCached_data">
                                            <i class="fas fa-spinner fa-spin" aria-hidden="true"></i>
                                        </span>
                                    </span>
                                </div>
                                <div class="progress progress-xs m-t-sm bg-default">
                                    <div id="memCached_css" class="progress-bar bg-danger" data-toggle="tooltip" style="width: 100%"></div>
                                </div>
                                <div class="">
                                    <span class="pull-right text-danger" id="memBuffers">
                                        <i class="fas fa-spinner fa-spin" aria-hidden="true"></i>
                                    </span>
                                    <span><i class="fas fa-layer-group fa-fw" aria-hidden="true"></i> 内存缓冲
                                        <span class="badge badge-sm bg-dark" id="memBuffers_data">
                                            <i class="fas fa-spinner fa-spin" aria-hidden="true"></i>
                                        </span>
                                    </span>
                                </div>
                                <div class="progress progress-xs m-t-sm bg-default">
                                    <div id="memBuffers_css" class="progress-bar bg-danger" data-toggle="tooltip" style="width: 100%"></div>
                                </div>
                                <div class="">
                                    <span class="pull-right text-danger" id="state_s">
                                        <i class="fas fa-spinner fa-spin" aria-hidden="true"></i>
                                    </span>
                                    <span><i class="fas fa-tachometer-alt fa-fw" aria-hidden="true"></i> 系统负载
                                        <span id="state">
                                            <span class="badge badge-sm bg-dark">
                                                <i class="fas fa-spinner fa-spin" aria-hidden="true"></i>
                                            </span>
                                        </span>
                                    </span>
                                </div>
                                <div class="progress progress-xs m-t-sm bg-default">
                                    <div id="state_css" class="progress-bar bg-danger" data-toggle="tooltip" style="width: 100%"></div>
                                </div>
                                <div class="">
                                    <span class="pull-right text-danger" id="cacheHitRate">
                                        <i class="fas fa-spinner fa-spin" aria-hidden="true"></i>
                                    </span>
                                    <span><i class="fas fa-bolt fa-fw" aria-hidden="true"></i> 缓存命中率</span>
                                </div>
                                <div class="progress progress-xs m-t-sm bg-default">
                                    <div id="cacheHitRate_css" class="progress-bar bg-info" data-toggle="tooltip" style="width: 0%"></div>
                                </div>
                            </div>
                            <div class="col-sm-4 b-l b-light visible-lg visible-md">
                                <div class="m-t-xs m-b-xs font-bold">网络状态</div>
                                <div class="">
                                    <span class="pull-right text-default" id="io">
                                        <i class="fas fa-spinner fa-spin" aria-hidden="true"></i>
                                    </span>
                                    <span><i class="fas fa-exchange-alt fa-fw" aria-hidden="true"></i> IO</span>
                                </div>
                                <br />
                                <div class="">
                                    <span class="pull-right text-default" id="io1">
                                        <i class="fas fa-spinner fa-spin" aria-hidden="true"></i>
                                    </span>
                                    <span><i class="fas fa-random fa-fw" aria-hidden="true"></i> 实时IO</span>
                                </div>
                                <br />
                                <div class="">
                                    <span class="pull-right text-default" id="eth">
                                        <i class="fas fa-spinner fa-spin" aria-hidden="true"></i>
                                    </span>
                                    <span><i class="fas fa-globe fa-fw" aria-hidden="true"></i> 网络</span>
                                </div>
                                <br />
                                <div class="">
                                    <span class="pull-right text-default" id="eth1">
                                        <i class="fas fa-spinner fa-spin" aria-hidden="true"></i>
                                    </span>
                                    <span><i class="fas fa-wifi fa-fw" aria-hidden="true"></i> 实时网络</span>
                                </div>
                                <br />
                                <div class="">
                                    <span class="pull-right text-default" id="time">
                                        <i class="fas fa-spinner fa-spin" aria-hidden="true"></i>
                                    </span>
                                    <span><i class="far fa-clock fa-fw" aria-hidden="true"></i> 服务器时间</span>
                                </div>
                                <br />
                                <div class="">
                                    <span class="pull-right text-default">
                                        <span class="badge badge-sm bg-dark"><?php echo $_SERVER['SERVER_SOFTWARE']; ?></span></span>
                                    <span><i class="fas fa-server fa-fw" aria-hidden="true"></i> WEB服务器</span>
                                </div>
                                <br />
                                <div class="">
                                    <span class="pull-right text-default">
                                        <span class="badge badge-sm bg-dark"><?php echo $_SERVER['SERVER_PROTOCOL']; ?></span>
                                    </span>
                                    <span><i class="fas fa-route fa-fw" aria-hidden="true"></i> 通信协议</span>
                                </div>
                                <br />
                                <div class="">
                                    <span class="pull-right text-default">
                                        <span class="badge badge-sm bg-dark"><?php echo PHP_VERSION; ?></span>
                                    </span>
                                    <span><i class="fas fa-code fa-fw" aria-hidden="true"></i> PHP版本</span>
                                </div>
                                <br />
                                <div class="">
                                    <span class="pull-right text-default" id="sys_info_badge">
                                        <i class="fas fa-spinner fa-spin" aria-hidden="true"></i>
                                    </span>
                                    <span><i class="fas fa-cogs fa-fw" aria-hidden="true"></i> 系统信息</span>
                                </div>
                                <br />
                                <div class="">
                                    <span class="pull-right text-default" id="os_info_badge">
                                        <i class="fas fa-spinner fa-spin" aria-hidden="true"></i>
                                    </span>
                                    <span><i class="fas fa-server fa-fw" aria-hidden="true"></i> 操作系统</span>
                                </div>
                                <br />
                            </div>
                            <div class="col-sm-4 b-l b-light visible-lg visible-md">
                                <div class="m-t-xs m-b-sm font-bold">访客信息</div>
                                <div class="">
                                    <span class="pull-right text-default" id="u_time">
                                        <i class="fas fa-spinner fa-spin" aria-hidden="true"></i>
                                    </span>
                                    <span><i class="fas fa-hourglass-half fa-fw" aria-hidden="true"></i> 持续运行</span>
                                </div>
                                <br />
                                <div class="">
                                    <span class="pull-right text-default" id="ip">
                                        <i class="fas fa-spinner fa-spin" aria-hidden="true"></i>
                                    </span>
                                    <span><i class="fas fa-map-marker-alt fa-fw" aria-hidden="true"></i> 您的IP</span>
                                </div>
                                <br />
                                <div class="">
                                    <span class="pull-right text-default" id="address">
                                        <i class="fas fa-spinner fa-spin" aria-hidden="true"></i>
                                    </span>
                                    <span><i class="fas fa-location-arrow fa-fw" aria-hidden="true"></i> 网络地址</span>
                                </div>
                                <br />
                                <div class="">
                                    <span class="pull-right text-default" id="b">
                                        <i class="fas fa-spinner fa-spin" aria-hidden="true"></i>
                                    </span>
                                    <span><i class="fab fa-chrome fa-fw" aria-hidden="true"></i> 浏览器信息</span>
                                </div>
                                <br />
                                <div class="">
                                    <span class="pull-right text-default" id="sys">
                                        <i class="fas fa-spinner fa-spin" aria-hidden="true"></i>
                                    </span>
                                    <span><i class="fas fa-laptop fa-fw" aria-hidden="true"></i> 您的设备</span>
                                </div>
                                <br />
                                <div class="">
                                    <span class="pull-right text-default">
                                        <span class="badge badge-sm bg-dark"><?php echo $_SERVER['REQUEST_METHOD']; ?></span></span>
                                    <span><i class="fas fa-paper-plane fa-fw" aria-hidden="true"></i> 请求方法</span>
                                </div>
                                <br />
                                <div class="">
                                    <span class="pull-right text-default">
                                        <span class="badge badge-sm bg-dark"><?php echo $_SERVER['HTTP_ACCEPT_LANGUAGE']; ?></span></span>
                                    <span><i class="fas fa-language fa-fw" aria-hidden="true"></i> 服务语言</span>
                                </div>
                                <br />
                                <div class="">
                                    <span class="pull-right text-default">
                                        <span class="badge badge-sm bg-dark"><?php echo (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') ? "HTTPS" : "HTTP"; ?></span>
                                    </span>
                                    <span><i class="fas fa-lock fa-fw" aria-hidden="true"></i> 连接类型</span>
                                </div>
                                <br />
                                <div class="">
                                    <span class="pull-right text-default">
                                        <span class="badge badge-sm bg-dark"><?php echo $_SERVER['HTTP_HOST']; ?></span>
                                    </span>
                                    <span><i class="fas fa-globe fa-fw" aria-hidden="true"></i> 当前域名</span>
                                </div>
                                <br />
                                <div class="">
                                    <span class="pull-right text-default" id="sys_times">
                                        <i class="fas fa-spinner fa-spin" aria-hidden="true"></i>
                                    </span>
                                    <span><i class="far fa-calendar-alt fa-fw" aria-hidden="true"></i> 您的设备时间</span>
                                </div>
                            </div>
                        </div>
                    </div>
                </li>

        [/zd-plane]

        3. 修改 footer.php 文件

        文件位置:usr/themes/handsome/component/footer.php

        在找到如下代码位置:

        <?php $this->options->bottomHtml(); ?>
        
           <!-- 在此追加代码 -->
        
        </body>
        </html><!--html end-->

        添加如下JavaScript代码:

        [zd-plane title="折叠标题" open="0"]

        <!-- 这里开始是新追加的内容 -->
        <script>
        var stateUrl = '/serverInfo.php';
            var se_rx = null;
            var se_tx = null;
            var si_rx = null;
            var si_tx = null;
            var lastCachedValue = 0;
            var lastBuffersValue = 0;
            var cacheHitRate = 0;
        
            function returnFloat(value) {
                return value.toFixed(2) + '%';
        }
        
            function floats(value) {
            return value.toFixed(2);
        }
        
        function getPercent(curNum, totalNum, isHasPercentStr) {
            curNum = parseFloat(curNum);
            totalNum = parseFloat(totalNum);
        
            if (isNaN(curNum) || isNaN(totalNum)) {
                return 'Error';
            }
        
            return isHasPercentStr ?
                totalNum <= 0 ? '0%' : (Math.round(curNum / totalNum * 10000) / 100.00 + '%') :
                    totalNum <= 0 ? 0 : (Math.round(curNum / totalNum * 10000) / 100.00 + '%');
        }
        
        function getPercents(curNum, totalNum, isHasPercentStr) {
            curNum = parseFloat(curNum);
            totalNum = parseFloat(totalNum);
        
            if (isNaN(curNum) || isNaN(totalNum)) {
                return 'Error';
            }
        
            return isHasPercentStr ?
                totalNum <= 0 ? '0%' : (Math.round(curNum / totalNum * 10000) / 100.00) :
                totalNum <= 0 ? 0 : (Math.round(curNum / totalNum * 10000) / 100.00);
        }
        
            function setSize(value, d) {
            switch (d) {
                case 'bit':
                        return bit = value * 8;
                    break;
                case 'bytes':
                    return value;
                    break;
                case 'kb':
                        return value / 1024;
                    break;
                case 'mb':
                        return value / 1024 / 1024;
                    break;
                case 'gb':
                        return value / 1024 / 1024 / 1024;
                    break;
                case 'tb':
                        return value / 1024 / 1024 / 1024 / 1024;
                    break;
            }
        }
        
            function ForDight(Dight) {
                if (Dight < 0) {
                    var Last = 0 + "B/s";
                } else if (Dight < 1024) {
                    var Last = setSize(Dight, 'bytes').toFixed(0) + "B/s";
                } else if (Dight < 1048576) {
                    var Last = floats(setSize(Dight, 'kb')) + "K/s";
                } else {
                    var Last = floats(setSize(Dight, 'mb')) + "MB/s";
            }
            return Last; 
        }
        
            function state() {
            $.ajax({
                url: stateUrl,
                type: 'get',
                dataType: 'json',
                data: {
                        action: 'fetch',
                },
                    beforeSend: function() {
          
                },
                    complete: function() {
          
                },
                    error: function(xhr, status, error) {
                        console.error("AJAX Error:", status, error);
                        // Maybe show a global error message in the UI
                }, 
                    success: function(data) {
                        // Defensively check for data and nested properties
                        var serverStatus = data.serverStatus || {};
                        var serverInfo = data.serverInfo || {};
                        var networkStats = data.networkStats || {};
                        var networks = networkStats.networks || {};
        
                        // CPU Usage
                        try {
                            var cpuData = serverStatus.cpuUsage || {};
                            var cpu = (parseFloat(cpuData['user']) || 0) + (parseFloat(cpuData['nice']) || 0) + (parseFloat(cpuData['sys']) || 0);
                    $("#cpu").html(returnFloat(cpu));
                            $("#cpu_css").css("width", returnFloat(cpu));
                            if (cpu < 70) {
                                $("#cpu_css").removeClass().addClass("progress-bar bg-success");
                                $("#cpu").removeClass().addClass("pull-right text-success");
                            } else if (cpu >= 90) {
                                $("#cpu_css").removeClass().addClass("progress-bar bg-danger");
                                $("#cpu").removeClass().addClass("pull-right text-danger");
                            } else {
                                $("#cpu_css").removeClass().addClass("progress-bar bg-warning");
                                $("#cpu").removeClass().addClass("pull-right text-warning");
                    }
                        } catch (e) {
                            console.error("Error processing CPU:", e);
                            $("#cpu").html('Error');
                        }
        
                        // Memory Usage
                        try {
                            var memData = serverStatus.memRealUsage || {};
                            var memory_value = memData.value || 0;
                            var memory_max = memData.max || 1; // Avoid division by zero
                            var memPercent = getPercent(memory_value, memory_max, true);
                            var me = getPercents(memory_value, memory_max, false);
              
                            $("#memory").html(memPercent);
                            $("#memory_css").css("width", memPercent);
        
                            if (me < 70) {
                                $("#memory_css").removeClass().addClass("progress-bar bg-success");
                                $("#memory").removeClass().addClass("pull-right text-success");
                            } else if (me >= 90) {
                                $("#memory_css").removeClass().addClass("progress-bar bg-danger");
                                $("#memory").removeClass().addClass("pull-right text-danger");
                            } else {
                                $("#memory_css").removeClass().addClass("progress-bar bg-warning");
                                $("#memory").removeClass().addClass("pull-right text-warning");
                    }
        
                            var memory_data_value = (floats(setSize(memory_value, 'mb')) > 1024) ? floats(setSize(memory_value, 'gb')) + "GB" : floats(setSize(memory_value, 'mb')) + "MB";
                            var memory_data_max = (floats(setSize(memory_max, 'mb')) > 1024) ? floats(setSize(memory_max, 'gb')) + "GB" : floats(setSize(memory_max, 'mb')) + "MB";
                            $("#memory_data").html(memory_data_value + " / " + memory_data_max);
                        } catch (e) {
                            console.error("Error processing Memory:", e);
                            $("#memory").html('Error');
                        }
        
                        try {
                            var diskData = serverInfo.diskUsage || {};
                            var disk_value = diskData.value || 0;
                            var disk_max = diskData.max || 0;
                            var diskPercent = getPercent(disk_value, disk_max, true);
                            var dk = getPercents(disk_value, disk_max, false);
        
                            $("#disk").html(diskPercent);
                            $("#disk_css").css("width", diskPercent);
        
                            if (dk < 70) {
                                $("#disk_css").removeClass().addClass("progress-bar bg-success");
                                $("#disk").removeClass().addClass("pull-right text-success");
                            } else if (dk >= 90) {
                                $("#disk_css").removeClass().addClass("progress-bar bg-danger");
                                $("#disk").removeClass().addClass("pull-right text-danger");
                            } else {
                                $("#disk_css").removeClass().addClass("progress-bar bg-warning");
                                $("#disk").removeClass().addClass("pull-right text-warning");
                    }
        
                            var disk_data_value = (floats(setSize(disk_value, 'mb')) > 1024) ? floats(setSize(disk_value, 'gb')) + "GB" : floats(setSize(disk_value, 'mb')) + "MB";
                            var disk_data_max = (floats(setSize(disk_max, 'mb')) > 1024) ? floats(setSize(disk_max, 'gb')) + "GB" : floats(setSize(disk_max, 'mb')) + "MB";
                            $("#disk_data").html(disk_data_value + " / " + disk_data_max);
                        } catch (e) { console.error("Error processing Disk:", e); }
        
                        try {
                            var memCachedData = serverStatus.memCached || {};
                            var memCached_value = memCachedData.value || 0;
                            var memCached_max = memCachedData.max || 0;
                            var memCachedPercent = getPercent(memCached_value, memCached_max, true);
                            var mem = getPercents(memCached_value, memCached_max, false);
        
                            $("#memCached").html(memCachedPercent);
                            $("#memCached_css").css("width", memCachedPercent);
        
                            if (mem < 70) {
                                $("#memCached_css").removeClass().addClass("progress-bar bg-success");
                                $("#memCached").removeClass().addClass("pull-right text-success");
                            } else if (mem >= 90) {
                                $("#memCached_css").removeClass().addClass("progress-bar bg-danger");
                                $("#memCached").removeClass().addClass("pull-right text-danger");
                            } else {
                                $("#memCached_css").removeClass().addClass("progress-bar bg-warning");
                                $("#memCached").removeClass().addClass("pull-right text-warning");
                    }
        
                            var memCached_data_value = (floats(setSize(memCached_value, 'mb')) > 1024) ? floats(setSize(memCached_value, 'gb')) + "GB" : floats(setSize(memCached_value, 'mb')) + "MB";
                            var memCached_data_max = (floats(setSize(memCached_max, 'mb')) > 1024) ? floats(setSize(memCached_max, 'gb')) + "GB" : floats(setSize(memCached_max, 'mb')) + "MB";
                            $("#memCached_data").html(memCached_data_value + " / " + memCached_data_max);
                        } catch (e) { console.error("Error processing MemCached:", e); }
        
                        try {
                            var memBuffersData = serverStatus.memBuffers || {};
                            var memBuffers_value = memBuffersData.value || 0;
                            var memBuffers_max = memBuffersData.max || 0;
                            var memBuffersPercent = getPercent(memBuffers_value, memBuffers_max, true);
                            var memB = getPercents(memBuffers_value, memBuffers_max, false);
        
                            $("#memBuffers").html(memBuffersPercent);
                            $("#memBuffers_css").css("width", memBuffersPercent);
        
                            if (memB < 70) {
                                $("#memBuffers_css").removeClass().addClass("progress-bar bg-success");
                                $("#memBuffers").removeClass().addClass("pull-right text-success");
                            } else if (memB >= 90) {
                                $("#memBuffers_css").removeClass().addClass("progress-bar bg-danger");
                                $("#memBuffers").removeClass().addClass("pull-right text-danger");
                            } else {
                                $("#memBuffers_css").removeClass().addClass("progress-bar bg-warning");
                                $("#memBuffers").removeClass().addClass("pull-right text-warning");
                    }
        
                            var memBuffers_data_value = (floats(setSize(memBuffers_value, 'mb')) > 1024) ? floats(setSize(memBuffers_value, 'gb')) + "GB" : floats(setSize(memBuffers_value, 'mb')) + "MB";
                            var memBuffers_data_max = (floats(setSize(memBuffers_max, 'mb')) > 1024) ? floats(setSize(memBuffers_max, 'gb')) + "GB" : floats(setSize(memBuffers_max, 'mb')) + "MB";
                            $("#memBuffers_data").html(memBuffers_data_value + " / " + memBuffers_data_max);
                        } catch (e) { console.error("Error processing MemBuffers:", e); }
        
                        try {
                            var sysLoad = serverStatus.sysLoad || [0, 0, 0];
                    var state = "";
                            for (var i = 0; i < sysLoad.length; i++) {
                                state += '<span class="badge badge-sm bg-dark">' + sysLoad[i] + '</span> '
                    }
                    $("#state").html(state);
                            var state_s = getPercent(sysLoad[0], 2, true);
                            var sta = getPercents(sysLoad[0], 2, false);
        
                            $("#state_css").css("width", state_s);
                    $("#state_s").html(state_s);
        
                            if (sta < 70) {
                                $("#state_css").removeClass().addClass("progress-bar bg-success");
                                $("#state_s").removeClass().addClass("pull-right text-success");
                            } else if (sta >= 90) {
                                $("#state_css").removeClass().addClass("progress-bar bg-danger");
                                $("#state_s").removeClass().addClass("pull-right text-danger");
                            } else {
                                $("#state_css").removeClass().addClass("progress-bar bg-warning");
                                $("#state_s").removeClass().addClass("pull-right text-warning");
                            }
                        } catch (e) { console.error("Error processing SysLoad:", e); }
          
                        $("#time").html('<span class="badge badge-sm bg-dark">' + data.serverInfo.serverTime + '</span>');
        
                        // 更新动态系统信息
                        if (data.serverInfo.sysInfo) {
                            $("#sys_info_badge").html('<span class="badge badge-sm bg-dark">' + data.serverInfo.sysInfo + '</span>');
                        }
                        if (data.serverInfo.osInfo) {
                            $("#os_info_badge").html('<span class="badge badge-sm bg-dark">' + data.serverInfo.osInfo + '</span>');
                        }
          
                        $("#u_time").html('<span class="badge badge-sm bg-dark">' + data.serverInfo.serverUptime["days"] + ' 天' + data.serverInfo.serverUptime["hours"] + ' 时 ' + data.serverInfo.serverUptime["mins"] + ' 分' + data.serverInfo.serverUptime["secs"] + ' 秒</span>');
        
                        // Network Stats
                        try {
                            var primaryNet = null;
                            var netPriority = ['eth0', 'ens3', 'ens33', 'eno1'];
                            for (var i = 0; i < netPriority.length; i++) {
                                if (networks[netPriority[i]]) {
                                    primaryNet = netPriority[i];
                                    break;
                                }
                            }
                            if (!primaryNet) {
                                for (var dev in networks) {
                                    if (dev !== 'lo' && dev.indexOf('veth') === -1 && dev.indexOf('br-') === -1 && dev.indexOf('docker') === -1) {
                                        primaryNet = dev;
                                        break;
                                    }
                                }
                            }
        
                            if (primaryNet && networks[primaryNet]) {
                                var net_tx = networks[primaryNet].tx || 0;
                                var net_rx = networks[primaryNet].rx || 0;
        
                                var aaa_tx = (floats(setSize(net_tx, 'mb')) > 1024) ?
                                    floats(setSize(net_tx, 'gb')) + "GB" :
                                    floats(setSize(net_tx, 'mb')) + "MB";
        
                                var aaa_rx = (floats(setSize(net_rx, 'mb')) > 1024) ?
                                    floats(setSize(net_rx, 'gb')) + "GB" :
                                    floats(setSize(net_rx, 'mb')) + "MB";
        
          
                                $("#eth").html('<span class="badge badge-sm bg-dark"><i class="fas fa-upload" aria-hidden="true"></i> ' + aaa_tx + '</span> ' +
                                    '<span class="badge badge-sm bg-dark"><i class="fas fa-download" aria-hidden="true"></i> ' + aaa_rx + '</span>');
        
                                if (se_tx === null) {
                                    se_tx = net_tx;
                                    se_rx = net_rx;
                                }
        
                                $("#eth1").html('<span class="badge badge-sm bg-dark"><i class="fas fa-cloud-upload-alt" aria-hidden="true"></i> ' + ForDight(net_tx - se_tx) + '</span> ' +
                                    '<span class="badge badge-sm bg-dark"><i class="fas fa-cloud-download-alt" aria-hidden="true"></i> ' + ForDight(net_rx - se_rx) + '</span>');
                                se_tx = net_tx;
                                se_rx = net_rx;
                            } else {
                                $("#eth").html('<span class="badge badge-sm bg-danger">N/A</span>');
                                $("#eth1").html('<span class="badge badge-sm bg-danger">N/A</span>');
                            }
        
                            var lo_data = networks['lo'] || {};
                            var lo_tx_val = lo_data.tx || 0;
                            var lo_rx_val = lo_data.rx || 0;
        
                            var lo_tx = (floats(setSize(lo_tx_val, 'mb')) > 1024) ?
                                floats(setSize(lo_tx_val, 'gb')) + "GB" :
                                floats(setSize(lo_tx_val, 'mb')) + "MB";
        
                            var lo_rx = (floats(setSize(lo_rx_val, 'mb')) > 1024) ?
                                floats(setSize(lo_rx_val, 'gb')) + "GB" :
                                floats(setSize(lo_rx_val, 'mb')) + "MB";
        
                            $("#io").html('<span class="badge badge-sm bg-dark"><i class="fas fa-upload" aria-hidden="true"></i> ' + lo_tx + '</span> ' +
                                '<span class="badge badge-sm bg-dark"><i class="fas fa-download" aria-hidden="true"></i> ' + lo_rx + '</span>');
        
                            if (si_tx === null) {
                                si_tx = lo_tx_val;
                                si_rx = lo_rx_val;
                            }
        
                            $("#io1").html('<span class="badge badge-sm bg-dark"><i class="fas fa-cloud-upload-alt" aria-hidden="true"></i> ' + ForDight(lo_tx_val - si_tx) + '</span> ' +
                                '<span class="badge badge-sm bg-dark"><i class="fas fa-cloud-download-alt" aria-hidden="true"></i> ' + ForDight(lo_rx_val - si_rx) + '</span>');
                            si_tx = lo_tx_val;
                            si_rx = lo_rx_val;
                        } catch(e) {
                            console.error("Error processing Network:", e);
                            $("#eth, #eth1, #io, #io1").html('<span class="badge badge-sm bg-danger">Error</span>');
                        }
        
                        // 计算缓存命中率
                        var memTotal = data.serverStatus.memRealUsage['max'];
                        var memCached = data.serverStatus.memCached['value'];
                        var memBuffers = data.serverStatus.memBuffers['value'];
        
                        // 计算缓存命中率 - 使用缓存和缓冲占总内存的百分比
                        var cacheRatio = ((memCached + memBuffers) / memTotal * 100).toFixed(2);
        
                        // 如果是第一次加载,初始化lastCachedValue和lastBuffersValue
                        if (lastCachedValue === 0 && lastBuffersValue === 0) {
                            lastCachedValue = memCached;
                            lastBuffersValue = memBuffers;
                            cacheHitRate = cacheRatio; // 初始值
                        } else {
                            // 计算缓存命中率变化趋势 (平滑处理)
                            cacheHitRate = (parseFloat(cacheHitRate) * 0.7 + parseFloat(cacheRatio) * 0.3).toFixed(2);
                            if (cacheHitRate < 0) cacheHitRate = 0;
                            if (cacheHitRate > 100) cacheHitRate = 100;
                            lastCachedValue = memCached;
                            lastBuffersValue = memBuffers;
                        }
        
                        // 添加缓存命中率信息
                        var hitRateHtml = '<span class="badge badge-sm bg-dark">' + cacheHitRate + '%</span>';
                        $("#cacheHitRate").html(hitRateHtml);
                        $("#cacheHitRate_css").css("width", cacheHitRate + "%");
        
                        // 根据命中率调整颜色
                        if (cacheHitRate < 30) {
                            $("#cacheHitRate_css").removeClass();
                            $("#cacheHitRate_css").addClass("progress-bar bg-danger");
                            $("#cacheHitRate").removeClass();
                            $("#cacheHitRate").addClass("pull-right text-danger");
                        }
                        if (cacheHitRate >= 30 && cacheHitRate < 70) {
                            $("#cacheHitRate_css").removeClass();
                            $("#cacheHitRate_css").addClass("progress-bar bg-warning");
                            $("#cacheHitRate").removeClass();
                            $("#cacheHitRate").addClass("pull-right text-warning");
                        }
                        if (cacheHitRate >= 70) {
                            $("#cacheHitRate_css").removeClass();
                            $("#cacheHitRate_css").addClass("progress-bar bg-success");
                            $("#cacheHitRate").removeClass();
                            $("#cacheHitRate").addClass("pull-right text-success");
                        }
                }
            });
        }
        
            function getNowFormatDate() {
            var date = new Date();
            var seperator1 = "-";
            var seperator2 = ":";
            var month = date.getMonth() + 1;
            var strDate = date.getDate();
            if (month >= 1 && month <= 9) {
              month = "0" + month;
            }
            if (strDate >= 0 && strDate <= 9) {
              strDate = "0" + strDate;
            }
                var currentdate = date.getFullYear() + seperator1 + month + seperator1 + strDate +
                    " " + date.getHours() + seperator2 + date.getMinutes() +
                    seperator2 + date.getSeconds();
            return currentdate;
        }
        
            function UserInfo() {
            // 先根据UA设置设备和浏览器信息
            var ua = navigator.userAgent;
            var browserInfo = getBrowserInfo(ua);
            var osInfo = getOsInfo(ua);
          
            // 立即显示浏览器和系统信息(不依赖API)
                $("#b").html('<span class="badge badge-sm bg-dark">' + browserInfo + '</span>');
                $("#sys").html('<span class="badge badge-sm bg-dark">' + osInfo + '</span>');
          
            // 使用我们自己的serverInfo.php获取IP信息,避免跨域问题
            $.ajax({
                type: "get",
                url: stateUrl, // 使用之前已定义的stateUrl变量 (指向serverInfo.php)
                    data: {
                        action: 'getip'
                    },
                async: true,
                dataType: "json",
                    beforeSend: function() {
                    $("#ip").html('<span class="badge badge-sm bg-dark">获取中...</span>');
                    $("#address").html('<span class="badge badge-sm bg-dark">获取中...</span>');
                },
                    error: function() {
                        $("#ip").html('<span class="badge badge-sm bg-dark">' + window.location.hostname + '</span>');
                    $("#address").html('<span class="badge badge-sm bg-dark">本地访问</span>');
                },
                    success: function(data) {
                        if (data && data.ip) {
                            $("#ip").html('<span class="badge badge-sm bg-dark">' + data.ip + '</span>');
          
                            if (data.location) {
                                $("#address").html('<span class="badge badge-sm bg-dark">' + data.location + '</span>');
                        } else {
                            $("#address").html('<span class="badge badge-sm bg-dark">本地网络</span>');
                        }
                    } else {
                            $("#ip").html('<span class="badge badge-sm bg-dark">' + window.location.hostname + '</span>');
                        $("#address").html('<span class="badge badge-sm bg-dark">本地访问</span>');
                    }
                }
            });
        }
        
        // 获取设备系统信息的函数
        function getOsInfo(ua) {
                if (!ua) ua = navigator.userAgent;
          
            if (ua.indexOf("Windows NT 10.0") != -1) {
                // 检测Win11
                if (ua.indexOf("Windows NT 10.0; Win64") != -1 && 
                    ((ua.indexOf("Chrome/") != -1 && parseInt(ua.split("Chrome/")[1]) >= 90) || 
                     (ua.indexOf("Firefox/") != -1 && parseInt(ua.split("Firefox/")[1]) >= 90))) {
                    return "Windows 11";
                }
                return "Windows 10";
            }
            if (ua.indexOf("Windows NT 6.3") != -1) return "Windows 8.1";
            if (ua.indexOf("Windows NT 6.2") != -1) return "Windows 8";
            if (ua.indexOf("Windows NT 6.1") != -1) return "Windows 7";
            if (ua.indexOf("Windows NT 6.0") != -1) return "Windows Vista";
            if (ua.indexOf("Windows NT 5.1") != -1) return "Windows XP";
                if (ua.indexOf("Android") != -1) return "Android " + (ua.match(/Android [\d\.]+;/) ? ua.match(/Android [\d\.]+;/)[0].replace(";", "").replace("Android ", "") : "");
            if (ua.indexOf("iPhone") != -1) return "iPhone";
            if (ua.indexOf("iPad") != -1) return "iPad";
            if (ua.indexOf("Mac OS X") != -1) return "macOS";
            if (ua.indexOf("Linux") != -1) return "Linux";
            if (ua.indexOf("CentOS") != -1) return "CentOS";
            if (ua.indexOf("Ubuntu") != -1) return "Ubuntu";
          
            return "未知设备";
        }
        
        // 获取浏览器信息
        function getBrowserInfo(ua) {
                if (!ua) ua = navigator.userAgent;
          
            // Edge
            if (ua.indexOf("Edg/") > -1) {
                return "Edge " + ua.match(/Edg\/([\d.]+)/)[1].split('.')[0];
            }
            // Chrome
            else if (ua.indexOf("Chrome/") > -1 && ua.indexOf("Safari/") > -1 && ua.indexOf("OPR/") == -1) {
                return "Chrome " + ua.match(/Chrome\/([\d.]+)/)[1].split('.')[0];
            }
            // Firefox
            else if (ua.indexOf("Firefox/") > -1) {
                return "Firefox " + ua.match(/Firefox\/([\d.]+)/)[1].split('.')[0];
            }
            // Opera
            else if (ua.indexOf("OPR/") > -1 || ua.indexOf("Opera/") > -1) {
                return "Opera " + (ua.match(/OPR\/([\d.]+)/) || ua.match(/Opera\/([\d.]+)/))[1].split('.')[0];
            }
            // Safari
            else if (ua.indexOf("Safari/") > -1 && ua.indexOf("Chrome/") == -1) {
                return "Safari " + (ua.match(/Version\/([\d.]+)/) ? ua.match(/Version\/([\d.]+)/)[1].split('.')[0] : "");
            }
            // 其他浏览器
            else {
                return "浏览器 " + (navigator.appVersion ? navigator.appVersion.split(" ")[0] : "");
            }
        }
        
            $('#StateData').click(function() {
            clearInterval(window.getnet);
            clearInterval(window.info);
        
                function updateAll() {
                    if ($('#StateDataPos').is('.open')) {
                    state();
                        $("#sys_times").html('<span class="badge badge-sm bg-dark">' + getNowFormatDate() + '</span>');
                }
                }
        
                // Call immediately after a short delay to allow dropdown to open
                setTimeout(updateAll, 50);
        
                window.getnet = setInterval(updateAll, 1000);
        
                if (!window.userInfoLoaded) {
            UserInfo();
                    window.userInfoLoaded = true;
                }
        });
        </script>
        <!-- 新追加的内容到此结束 -->

        [/zd-plane]

        4. 创建 serverInfo.php 文件

        在网站根目录创建 serverInfo.php 文件,内容如下:

        <?php
        
        header('Content-Type: application/json; charset=utf-8');
        header('Cache-Control: no-cache, must-revalidate');
        header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
        
        /**
         * Tries to get file contents, using file_get_contents and falling back to shell_exec('cat').
         * This can help in environments with restrictions like open_basedir.
         * @param string $file The path to the file.
         * @return string|false The file contents or false on failure.
         */
        function GetContents($file)
        {
            if (!@is_readable($file)) {
                return false;
            }
            $content = @file_get_contents($file);
            if ($content !== false) {
                return $content;
            }
            if (function_exists('shell_exec') && false === strpos(ini_get('disable_functions'), 'shell_exec')) {
                $output = shell_exec('cat ' . escapeshellarg($file));
                if ($output) {
                    return $output;
                }
            }
            return false;
        }
        
        function size_format($bytes, $decimals = 2)
        {
            $size = ['B', 'KB', 'MB', 'GB', 'TB', 'PB'];
            $factor = floor((strlen($bytes) - 1) / 3);
            return sprintf("%.{$decimals}f", $bytes / pow(1024, $factor)) . $size[$factor];
        }
        
        function netSize($bytes)
        {
            if ($bytes < 1024) return $bytes . ' B';
            if ($bytes < 1048576) return round($bytes / 1024, 2) . ' KB';
            if ($bytes < 1073741824) return round($bytes / 1048576, 2) . ' MB';
            return round($bytes / 1073741824, 2) . ' GB';
        }
        
        /**
         * 获取当前Unix时间戳
         * */
        $unixTimestamp = time();
        /**
         * 获取服务器总的运行时长
         * */
        $serverUptime =  getUpTime();
        /**
         * 获取服务器负载 以及CPU使用信息
         * */
        $serverLoad = GetLoad();
        $cpuUsage = GetCPUInfo();
        /**
         * 获取服务器内存信息
         * */
        $memoryInfo = GetMem();
        
        // 处理IP信息请求
        if (isset($_GET['action']) && $_GET['action'] == 'getip') {
            // 获取用户真实IP地址
            $ip = '';
            // 检查各种可能的代理头部
            $headers = [
                'HTTP_CF_CONNECTING_IP', // Cloudflare
                'HTTP_X_FORWARDED_FOR',  // 通用代理和CDN
                'HTTP_X_REAL_IP',        // Nginx代理
                'HTTP_CLIENT_IP',        // 客户端代理
                'HTTP_X_FORWARDED',      // 通用
                'HTTP_FORWARDED_FOR',    // 通用
                'HTTP_FORWARDED',        // 通用
                'HTTP_X_CLUSTER_CLIENT_IP', // 集群
                'HTTP_TRUE_CLIENT_IP',   // Akamai和Cloudflare
                'HTTP_X_CHAITIN_IP',     // 长亭雷池可能使用的头部
                'REMOTE_ADDR'            // 直接连接
            ];
        
            // 记录所有可能的IP来源(调试用)
            $debug_headers = [];
            foreach ($headers as $header) {
                if (!empty($_SERVER[$header])) {
                    $debug_headers[$header] = $_SERVER[$header];
                }
            }
        
            // 尝试获取真实IP
            foreach ($headers as $header) {
                if (!empty($_SERVER[$header])) {
                    $ip_array = explode(',', $_SERVER[$header]);
                    $ip = trim($ip_array[0]); // 第一个IP通常是客户端真实IP
                    break;
                }
            }
        
            // 简单过滤掉非法IP
            $ip = filter_var($ip, FILTER_VALIDATE_IP) ? $ip : '未知';
        
            // 获取地理位置信息(只对公网IP有效)
            $location = '';
            // 检查是否是内网IP
            if (!filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
                $location = '内网IP: ' . $ip; // 显示具体的内网IP地址
            } else {
                // 方法1:使用太平洋IP库(覆盖较全面,国内外都支持)
                $url = "http://whois.pconline.com.cn/ipJson.jsp?ip={$ip}&json=true";
                $ch = curl_init();
                curl_setopt($ch, CURLOPT_URL, $url);
                curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
                curl_setopt($ch, CURLOPT_TIMEOUT, 3);
                curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
                curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
                curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36');
                curl_setopt($ch, CURLOPT_ENCODING, 'gzip,deflate');
                $response = curl_exec($ch);
                $errno = curl_errno($ch);
                curl_close($ch);
        
                if ($response && !$errno) {
                    // 太平洋的接口返回的是GB2312编码,需要转换
                    $response = mb_convert_encoding($response, 'UTF-8', 'GBK');
                    $data = json_decode($response, true);
                    if ($data && isset($data['pro']) && isset($data['city'])) {
                        $region = '';
                        if (!empty($data['pro'])) {
                            $region .= $data['pro'];
                        }
                        if (!empty($data['city']) && $data['city'] != $data['pro']) {
                            $region .= ' ' . $data['city'];
                        }
                        // 根据IP段判断运营商
                        $carrier = judgeCarrier($ip);
                        if ($carrier) {
                            $region .= ' ' . $carrier;
                        }
                        $location = $region ? $region : '未知区域';
                    }
                }
        
                // 方法2:使用IpInfo API(国外IP支持较好)
                if (empty($location)) {
                    $url = "https://ipinfo.io/{$ip}/json";
                    $ch = curl_init();
                    curl_setopt($ch, CURLOPT_URL, $url);
                    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
                    curl_setopt($ch, CURLOPT_TIMEOUT, 3);
                    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
                    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
                    curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36');
                    $response = curl_exec($ch);
                    curl_close($ch);
        
                    if ($response) {
                        $data = json_decode($response, true);
                        if ($data && isset($data['region']) && isset($data['city'])) {
                            $region = '';
                            if (!empty($data['country'])) {
                                $region .= getCountryName($data['country']);
                            }
                            if (!empty($data['region'])) {
                                $region .= ' ' . $data['region'];
                            }
                            if (!empty($data['city'])) {
                                $region .= ' ' . $data['city'];
                            }
                            if (!empty($data['org'])) {
                                $region .= ' ' . preg_replace('/^AS\d+\s+/', '', $data['org']);
                            } else {
                                // 补充运营商信息
                                $carrier = judgeCarrier($ip);
                                if ($carrier) {
                                    $region .= ' ' . $carrier;
                                }
                            }
                            $location = $region ? $region : '未知区域';
                        }
                    }
                }
        
                // 方法3:使用IPIP.net的免费接口(国内移动网络支持较好)
                if (empty($location)) {
                    $url = "https://freeapi.ipip.net/{$ip}";
                    $ch = curl_init();
                    curl_setopt($ch, CURLOPT_URL, $url);
                    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
                    curl_setopt($ch, CURLOPT_TIMEOUT, 3);
                    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
                    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
                    curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36');
                    $response = curl_exec($ch);
                    curl_close($ch);
        
                    if ($response && $response != '{}') {
                        $data = json_decode($response, true);
                        if (is_array($data) && count($data) >= 4) {
                            // IPIP.net返回格式:["中国","福建","厦门","","移动"]
                            $region = '';
                            if (!empty($data[1])) {
                                $region .= $data[1]; // 省份
                            }
                            if (!empty($data[2]) && $data[2] != $data[1]) {
                                $region .= ' ' . $data[2]; // 城市
                            }
                            if (!empty($data[4])) {
                                $region .= ' ' . $data[4]; // 运营商
                            } else {
                                // 补充运营商信息
                                $carrier = judgeCarrier($ip);
                                if ($carrier) {
                                    $region .= ' ' . $carrier;
                                }
                            }
                            $location = $region ? $region : '未知区域';
                        }
                    }
                }
        
                // 方法4:使用淘宝IP库(作为备用)
                if (empty($location)) {
                    $url = "https://ip.taobao.com/outGetIpInfo?ip=" . $ip . "&accessKey=alibaba-inc";
                    $opts = array(
                        'http' => array(
                            'method' => "GET",
                            'timeout' => 3,
                        )
                    );
                    $context = stream_context_create($opts);
                    $response = @file_get_contents($url, false, $context);
        
                    if ($response !== false) {
                        $data = json_decode($response, true);
                        if (isset($data['data']) && $data['data']) {
                            $result = $data['data'];
                            $region = '';
                            if (!empty($result['region'])) {
                                $region .= $result['region'];
                            }
                            if (!empty($result['city']) && $result['city'] != $result['region']) {
                                $region .= ' ' . $result['city'];
                            }
                            if (!empty($result['isp'])) {
                                $region .= ' ' . $result['isp'];
                            } else {
                                // 补充运营商信息
                                $carrier = judgeCarrier($ip);
                                if ($carrier) {
                                    $region .= ' ' . $carrier;
                                }
                            }
                            $location = $region ? $region : '未知区域';
                        }
                    }
                }
        
                // 方法5:极速数据网络IP库(移动网络特别友好)
                if (empty($location)) {
                    $url = "http://ip.jisuapi.com/api/ip/geo?ip={$ip}";
                    $ch = curl_init();
                    curl_setopt($ch, CURLOPT_URL, $url);
                    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
                    curl_setopt($ch, CURLOPT_TIMEOUT, 3);
                    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
                    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
                    $response = curl_exec($ch);
                    curl_close($ch);
        
                    if ($response) {
                        $data = json_decode($response, true);
                        if (isset($data['result']) && $data['result']) {
                            $result = $data['result'];
                            $region = '';
                            if (!empty($result['province'])) {
                                $region .= $result['province'];
                            }
                            if (!empty($result['city']) && $result['city'] != $result['province']) {
                                $region .= ' ' . $result['city'];
                            }
                            if (!empty($result['isp'])) {
                                $region .= ' ' . $result['isp'];
                            } else {
                                // 补充运营商信息
                                $carrier = judgeCarrier($ip);
                                if ($carrier) {
                                    $region .= ' ' . $carrier;
                                }
                            }
                            $location = $region ? $region : '未知区域';
                        }
                    }
                }
        
                // 方法6:仅使用IP段进行精准匹配(最后保障)
                if (empty($location)) {
                    // 根据IP段匹配位置信息
                    $ipLocation = getIpLocation($ip);
                    if ($ipLocation) {
                        $location = $ipLocation;
                    } else {
                        // 至少返回运营商信息
                        $carrier = judgeCarrier($ip);
                        if ($carrier) {
                            $location = $carrier;
                        } else {
                            $location = "公网IP";
                        }
                    }
                }
            }
        
            // 返回IP信息
            echo json_encode([
                'ip' => $ip,
                'location' => $location,
                'debug' => $debug_headers // 添加调试信息
            ]);
            exit;
        }
        
        /**
         * 根据IP地址判断归属运营商
         * @param string $ip IP地址
         * @return string 运营商名称
         */
        function judgeCarrier($ip)
        {
            // 特殊IP段映射
            $special_ip_carriers = [
                // 移动特殊段
                '39.128.' => '中国移动',
                '39.129.' => '中国移动',
                '39.130.' => '中国移动',
                '39.131.' => '中国移动',
                '39.132.' => '中国移动',
                '39.133.' => '中国移动',
                '39.134.' => '中国移动',
                '39.135.' => '中国移动',
                '39.136.' => '中国移动',
                '39.137.' => '中国移动',
                '39.138.' => '中国移动',
                '39.139.' => '中国移动',
                '39.140.' => '中国移动',
                '39.141.' => '中国移动',
                '39.142.' => '中国移动',
                '39.143.' => '中国移动',
                '39.144.' => '中国移动',
                '39.145.' => '中国移动',
                '39.146.' => '中国移动',
                '39.147.' => '中国移动',
                '39.148.' => '中国移动',
                '39.149.' => '中国移动',
                '39.150.' => '中国移动',
                '39.151.' => '中国移动',
                '39.152.' => '中国移动',
                '39.153.' => '中国移动',
                '39.154.' => '中国移动',
                '39.155.' => '中国移动',
                '39.156.' => '中国移动',
                '39.157.' => '中国移动',
                '39.158.' => '中国移动',
                '39.159.' => '中国移动',
                '39.176.' => '中国移动',
                '40.128.' => '中国移动',
                '40.129.' => '中国移动',
                '40.130.' => '中国移动',
                '41.128.' => '中国移动',
                '42.128.' => '中国移动',
                '43.128.' => '中国移动',
        
                // 联通特殊段
                '44.128.' => '中国联通',
                '45.128.' => '中国联通',
                '46.128.' => '中国联通',
        
                // 电信特殊段
                '48.128.' => '中国电信',
                '49.128.' => '中国电信',
                '50.128.' => '中国电信',
                '51.128.' => '中国电信',
            ];
        
            // 检查特殊IP段映射
            foreach ($special_ip_carriers as $prefix => $carrier) {
                if (strpos($ip, $prefix) === 0) {
                    return $carrier;
                }
            }
        
            // 移动
            $china_mobile = [
                '39',
                '40',
                '41',
                '42',
                '43', // 新的移动段
                '47.0',
                '47.1',
                '47.2',
                '47.3', // 兼容部分联通和移动混用
                '178.',
                '180.',
                '182.',
                '183.',
                '184.',
                '157.',
                '158.',
                '159.',
                '165.',
                '172.',
                '120.204.',
                '120.205.',
                '120.206.',
                '120.207.',
                '120.208.',
                '120.209.',
                '120.210.',
                '120.211.',
                '120.212.',
                '120.213.',
                '120.214.',
                '120.215.',
                '221.130.',
                '221.131.',
                '221.132.',
                '221.133.',
                '221.134.',
                '221.135.',
                '221.136.',
                '221.137.',
                '221.138.',
                '221.139.',
                '211.103.',
                '211.137.',
            ];
        
            // 联通
            $china_unicom = [
                '44',
                '45',
                '46', // 新的联通段
                '47.4',
                '47.5',
                '47.6',
                '47.7',
                '47.8',
                '47.9', // 兼容部分联通和移动混用
                '130.',
                '131.',
                '132.',
                '155.',
                '156.',
                '186.',
                '145.',
                '146.',
                '166.',
                '175.',
                '171.',
                '175.',
                '176.',
                '185.',
                '186.',
                '166.',
                '120.64.',
                '120.65.',
                '120.66.',
                '120.67.',
                '120.68.',
                '120.69.',
                '120.70.',
                '120.71.',
                '120.72.',
                '120.73.',
                '120.74.',
                '120.75.',
                '120.76.',
                '120.77.',
                '120.78.',
                '120.79.',
                '120.80.',
                '120.81.',
                '121.76.',
                '121.77.',
                '121.78.',
                '121.79.',
                '121.80.',
                '121.81.',
                '218.100.',
                '218.104.',
                '218.108.',
                '211.90.',
                '211.91.',
                '211.92.',
                '211.93.',
                '211.94.',
                '211.95.',
                '211.96.',
                '211.97.',
                '211.98.',
                '211.99.',
                '211.100.',
                '211.101.',
                '211.102.',
            ];
        
            // 电信
            $china_telecom = [
                '48',
                '49',
                '50',
                '51', // 新的电信段
                '133.',
                '153.',
                '173.',
                '177.',
                '180.',
                '181.',
                '189.',
                '199.',
                '120.128.',
                '120.129.',
                '120.130.',
                '120.131.',
                '120.132.',
                '120.133.',
                '120.134.',
                '120.135.',
                '120.136.',
                '120.137.',
                '120.138.',
                '120.139.',
                '120.140.',
                '120.141.',
                '120.142.',
                '120.143.',
                '120.144.',
                '120.145.',
                '113.64.',
                '113.65.',
                '113.66.',
                '113.67.',
                '113.68.',
                '113.69.',
                '113.70.',
                '113.71.',
                '113.72.',
                '113.73.',
                '113.74.',
                '113.75.',
                '125.64.',
                '125.65.',
                '125.66.',
                '125.67.',
                '125.68.',
                '125.69.',
                '125.70.',
                '125.71.',
                '125.72.',
                '125.73.',
                '125.74.',
                '125.75.',
                '210.5.',
                '210.12.',
                '210.14.',
                '210.21.',
                '210.32.',
                '210.51.',
                '210.52.',
                '210.77.',
                '210.192.',
            ];
        
            // 铁通/广电/其他
            $china_other = [
                '36',
                '37',
                '38', // 其他杂段
                '1700',
                '1705',
                '1709', // 虚拟运营商
            ];
        
            // 特定省份IP段
            $province_ip_map = [
                // 河南移动IP段范围
                '39.144.25' => '河南 南阳 中国移动',
                '39.144.26' => '河南 南阳 中国移动',
                '39.144.27' => '河南 南阳 中国移动',
        
                // 福建电信IP段范围
                '120.32.2' => '福建 厦门 中国电信',
                '120.32.3' => '福建 厦门 中国电信',
                '120.32.4' => '福建 厦门 中国电信',
            ];
        
            // 检查特定省份IP段映射
            foreach ($province_ip_map as $prefix => $location) {
                if (strpos($ip, $prefix) === 0) {
                    return $location;
                }
            }
        
            foreach ($china_mobile as $prefix) {
                if (strpos($ip, $prefix) === 0) {
                    return '中国移动';
                }
            }
        
            foreach ($china_unicom as $prefix) {
                if (strpos($ip, $prefix) === 0) {
                    return '中国联通';
                }
            }
        
            foreach ($china_telecom as $prefix) {
                if (strpos($ip, $prefix) === 0) {
                    return '中国电信';
                }
            }
        
            foreach ($china_other as $prefix) {
                if (strpos($ip, $prefix) === 0) {
                    return '其他运营商';
                }
            }
        
            return '';
        }
        
        /**
         * 根据IP前缀识别地理位置
         * @param string $ip IP地址
         * @return string 地理位置
         */
        function getIpLocation($ip)
        {
            // 特定地区IP段映射表
            $ip_location_map = [
                // 河南移动
                '39.144.2' => '河南 中国移动',
                '39.144.25' => '河南 南阳 中国移动',
                '39.144.26' => '河南 南阳 中国移动',
        
                // 福建电信
                '120.32.2' => '福建 厦门 中国电信',
                '120.32.3' => '福建 厦门 中国电信',
        
                // 北京联通
                '111.200.' => '北京 中国联通',
                '111.201.' => '北京 中国联通',
        
                // 上海电信
                '180.166.' => '上海 中国电信',
                '180.167.' => '上海 中国电信',
        
                // 广东移动
                '120.231.' => '广东 中国移动',
                '120.232.' => '广东 中国移动',
        
                // 浙江电信
                '115.192.' => '浙江 杭州 中国电信',
                '115.193.' => '浙江 杭州 中国电信',
            ];
        
            // 逐段检查,从最长前缀到最短
            $segments = explode('.', $ip);
        
            // 检查前三段 (如 192.168.1)
            if (count($segments) >= 3) {
                $prefix3 = $segments[0] . '.' . $segments[1] . '.' . $segments[2];
                if (isset($ip_location_map[$prefix3])) {
                    return $ip_location_map[$prefix3];
                }
            }
        
            // 检查前两段 (如 192.168)
            if (count($segments) >= 2) {
                $prefix2 = $segments[0] . '.' . $segments[1];
                if (isset($ip_location_map[$prefix2])) {
                    return $ip_location_map[$prefix2];
                }
            }
        
            // 检查第一段 (如 192)
            if (count($segments) >= 1) {
                $prefix1 = $segments[0];
                if (isset($ip_location_map[$prefix1])) {
                    return $ip_location_map[$prefix1];
                }
            }
        
            return '';
        }
        
        /**
         * 获取国家名称(将ISO代码转为中文名称)
         * @param string $code 国家代码
         * @return string 国家名称
         */
        function getCountryName($code)
        {
            $countries = [
                'CN' => '中国',
                'US' => '美国',
                'JP' => '日本',
                'KR' => '韩国',
                'GB' => '英国',
                'DE' => '德国',
                'FR' => '法国',
                'RU' => '俄罗斯',
                'CA' => '加拿大',
                'AU' => '澳大利亚',
                'HK' => '香港',
                'TW' => '台湾',
            ];
        
            return isset($countries[$code]) ? $countries[$code] : $code;
        }
        
        /**
         * 获取详细的操作系统信息
         * @return string
         */
        function getDetailedOsInfo()
        {
            if (stristr(PHP_OS, 'WIN')) {
                return php_uname('s') . ' ' . php_uname('r');
            }
            if (@is_readable('/etc/os-release')) {
                $vars = parse_ini_file('/etc/os-release');
                if (!empty($vars['PRETTY_NAME'])) return $vars['PRETTY_NAME'];
                if (!empty($vars['NAME'])) return $vars['NAME'] . (isset($vars['VERSION']) ? ' ' . $vars['VERSION'] : '');
            }
            return php_uname('s') . ' ' . php_uname('r');
        }
        
        // 定义要输出的内容  
        $serverInfo = array(
            'serverTime' => date('Y-m-d H:i:s', $unixTimestamp),
            'serverUptime' => array(
                'days' => $serverUptime['days'],
                'hours' => $serverUptime['hours'],
                'mins' => $serverUptime['mins'],
                'secs' => $serverUptime['secs']
            ),
            'serverUtcTime' => date('Y/m/d H:i:s', $unixTimestamp),
            'diskUsage' => array(
                'value' => disk_total_space(__FILE__) - disk_free_space(__FILE__),
                'max' => disk_total_space(__FILE__)
            ),
            'sysInfo' => php_uname('s') . ' ' . php_uname('r'),
            'osInfo' => getDetailedOsInfo(), // This is new
        );
        
        $serverStatus = array(
            'sysLoad' => array($serverLoad['1m'], $serverLoad['5m'], $serverLoad['15m']),
            'cpuUsage' => array(
                'user' => $cpuUsage['user'],
                'nice' => $cpuUsage['nice'],
                'sys' => $cpuUsage['sys'],
                'idle' => $cpuUsage['idle']
            ),
            'memRealUsage' => array(
                'value' => $memoryInfo['mRealUsed'],
                'max' => $memoryInfo['mTotal']
            ),
            'memBuffers' => array(
                'value' => $memoryInfo['mBuffers'],
                'max' => $memoryInfo['mTotal']
            ),
            'memCached' => array(
                'value' => $memoryInfo['mCached'],
                'max' => $memoryInfo['mTotal']
            ),
            'swapUsage' => array(
                'value' => $memoryInfo['swapUsed'],
                'max' => $memoryInfo['swapTotal']
            ),
            'swapCached' => array(
                'value' => $memoryInfo['swapCached'],
                'max' => $memoryInfo['swapTotal']
            )
        );
        
        $networkStats = array(
            'networks' => GetNetwork()
        );
        // 将以上内容合并为一个数组  
        $output = array(
            'serverInfo' => $serverInfo,
            'serverStatus' => $serverStatus,
            'networkStats' => $networkStats
        );
        
        // 将数组转换为JSON字符串并输出  
        echo json_encode($output);
        
        /**
         * 获取系统运行时长
         *
         * @return array
         */
        function getUpTime()
        {
            $uptime_str = GetContents("/proc/uptime");
            if (false === $uptime_str) {
                return array('days' => 0, 'hours' => 0, 'mins' => 0, 'secs' => 0);
            }
            $uptime = (float)$uptime_str;
            $days = floor($uptime / 86400);
            $hours = floor(($uptime % 86400) / 3600);
            $minutes = floor((($uptime % 86400) % 3600) / 60);
            $seconds = floor(($uptime % 3600) % 60);
            return array(
                'days' => $days,
                'hours' => $hours,
                'mins' => $minutes,
                'secs' => $seconds
            );
        }
        
        /**
         * 获取系统负载
         *
         * @return array|false|string[]
         */
        function GetLoad()
        {
            $str = GetContents("/proc/loadavg");
            if (false === $str) {
                return ['1m' => 0, '5m' => 0, '15m' => 0];
            }
            $loads = explode(' ', $str);
            if (count($loads) >= 3) {
                return [
                    '1m'  => $loads[0],
                    '5m'  => $loads[1],
                    '15m' => $loads[2],
                ];
            }
            return ['1m' => 0, '5m' => 0, '15m' => 0];
        }
        
        function GetCPUInfo()
        {
            $load = sys_getloadavg();
            $user = $load[0];
            $nice = $load[1];
            $sys = $load[2];
            $idle = 100 - ($user + $nice + $sys);
            return [
                'user' => $user,
                'nice' => $nice,
                'sys' => $sys,
                'idle' => $idle,
            ];
        }
        
        /**
         * 内存信息
         *
         * @param bool $bFormat 格式化
         *
         * @return array
         */
        function GetMem(bool $bFormat = false)
        {
            $defaults = [
                'mTotal' => 0,
                'mFree' => 0,
                'mBuffers' => 0,
                'mCached' => 0,
                'mUsed' => 0,
                'mPercent' => 0,
                'mRealUsed' => 0,
                'mRealFree' => 0,
                'mRealPercent' => 0,
                'mCachedPercent' => 0,
                'swapTotal' => 0,
                'swapFree' => 0,
                'swapUsed' => 0,
                'swapPercent' => 0,
                'swapCached' => 0
            ];
        
            $str = GetContents("/proc/meminfo");
            if (false === $str) {
                return $defaults;
            }
        
            preg_match_all("/MemTotal\s{0,}\:+\s{0,}([\d\.]+).+?MemFree\s{0,}\:+\s{0,}([\d\.]+).+?Cached\s{0,}\:+\s{0,}([\d\.]+).+?SwapTotal\s{0,}\:+\s{0,}([\d\.]+).+?SwapFree\s{0,}\:+\s{0,}([\d\.]+)/s", $str, $mems);
            preg_match_all("/Buffers\s{0,}\:+\s{0,}([\d\.]+)/s", $str, $buffers);
            preg_match("/SwapCached\s{0,}\:+\s{0,}([\d\.]+)/s", $str, $swap_cached_match);
        
            if (!isset($mems[1][0], $mems[2][0], $mems[3][0], $mems[4][0], $mems[5][0], $buffers[1][0])) {
                return $defaults;
            }
        
            $mtotal    = $mems[1][0] * 1024;
            $mfree     = $mems[2][0] * 1024;
            $mbuffers  = $buffers[1][0] * 1024;
            $mcached   = $mems[3][0] * 1024;
            $stotal    = $mems[4][0] * 1024;
            $sfree     = $mems[5][0] * 1024;
            $swap_cached = !empty($swap_cached_match[1]) ? $swap_cached_match[1] * 1024 : 0;
        
            $mused     = $mtotal - $mfree;
            $sused     = $stotal - $sfree;
            $mrealused = $mtotal - $mfree - $mcached - $mbuffers;
        
            $rtn['mTotal']         = !$bFormat ? $mtotal : size_format($mtotal, 1);
            $rtn['mFree']          = !$bFormat ? $mfree : size_format($mfree, 1);
            $rtn['mBuffers']       = !$bFormat ? $mbuffers : size_format($mbuffers, 1);
            $rtn['mCached']        = !$bFormat ? $mcached : size_format($mcached, 1);
            $rtn['mUsed']          = !$bFormat ? ($mtotal - $mfree) : size_format($mtotal - $mfree, 1);
            $rtn['mPercent']       = (floatval($mtotal) != 0) ? round($mused / $mtotal * 100, 1) : 0;
            $rtn['mRealUsed']      = !$bFormat ? $mrealused : size_format($mrealused, 1);
            $rtn['mRealFree']      = !$bFormat ? ($mtotal - $mrealused) : size_format($mtotal - $mrealused, 1);
            $rtn['mRealPercent']   = (floatval($mtotal) != 0) ? round($mrealused / $mtotal * 100, 1) : 0;
            $rtn['mCachedPercent'] = (floatval($mcached) != 0) ? round($mcached / $mtotal * 100, 1) : 0;
            $rtn['swapTotal']      = !$bFormat ? $stotal : size_format($stotal, 1);
            $rtn['swapFree']       = !$bFormat ? $sfree : size_format($sfree, 1);
            $rtn['swapUsed']       = !$bFormat ? $sused : size_format($sused, 1);
            $rtn['swapPercent']    = (floatval($stotal) != 0) ? round($sused / $stotal * 100, 1) : 0;
            $rtn['swapCached']     = !$bFormat ? $swap_cached : size_format($swap_cached, 1);
            return $rtn;
        }
        
        /**
         * 获取网络数据
         *
         * @param bool $bFormat
         *
         * @return array
         */
        function GetNetwork(bool $bFormat = false)
        {
            $rtn     = [];
            $netstat = GetContents('/proc/net/dev');
            if (false === $netstat) {
                return [];
            }
        
            $bufe = preg_split("/\n/", $netstat, -1, PREG_SPLIT_NO_EMPTY);
            foreach ($bufe as $buf) {
                if (preg_match('/:/', $buf)) {
                    list($dev_name, $stats_list) = preg_split('/:/', $buf, 2);
                    $dev_name = trim($dev_name);
        
                    $stats = preg_split('/\s+/', trim($stats_list));
                    if (count($stats) < 10) {
                        continue;
                    }
        
                    $rtn[$dev_name]['name']       = $dev_name;
                    $rtn[$dev_name]['rx']    = !$bFormat ? $stats[0] : netSize($stats[0]);
                    $rtn[$dev_name]['in_packets'] = $stats[1];
                    $rtn[$dev_name]['in_errors']  = $stats[2];
                    $rtn[$dev_name]['in_drop']    = $stats[3];
        
                    $rtn[$dev_name]['tx'] = !$bFormat ? $stats[8] : netSize($stats[8]);
                    $rtn[$dev_name]['out_packets'] = $stats[9];
                    $rtn[$dev_name]['out_errors']  = $stats[10] ?? 0;
                    $rtn[$dev_name]['out_drop']    = $stats[11] ?? 0;
                }
            }
        
            return $rtn;
        }

        使用宝塔面板配置说明

        若使用宝塔面板环境,请修改网站根目录中的 .user.ini 文件,在 open_basedir 后面追加 :/proc/

        open_basedir=/www/wwwroot/your.domain/:/tmp/:/proc/

        PHP安全设置调整(可选)

        在Debian系统上,需要确保PHP可以执行shell命令。修改php.ini文件:

        1. 找到 disable_functions 行,确保 shell_execexecsystem 未被禁用
        2. 如果在该行找到这些函数,请删除它们(用逗号分隔)

        Apache配置(可选)

        如果使用Apache服务器,可能需要修改配置允许执行系统命令:

        1. 编辑网站的虚拟主机配置文件或 .htaccess 文件
        2. 添加以下内容:

        <Directory /var/www/html>
            Options +ExecCGI
        </Directory>

        常见问题排查

        如果遇到问题,可以尝试以下排查步骤:

        1. 检查PHP是否有权限执行shell命令cd /path/to/your/website php -r "echo shell_exec('whoami');"如果返回用户名,说明PHP有权限执行shell命令
        2. 检查是否可以访问/proc目录php -r "var_dump(file_get_contents('/proc/uptime'));"如果返回内容而不是false或错误,说明可以访问/proc目录
        3. 检查必要的命令是否可用which top free ifconfig ip确保这些命令都可用
        4. CPU核心数默认是8核,可在headnav.php中修改
        5. 数据加载缓慢时尝试调整PHP版本为8.0并按照上述教程解禁函数,然后重启服务器

        如有其他问题,欢迎在评论区留言