分类: 服务器

  • 在vercel上部署typecho

    TL;DR

    通过vercel第三方库来运行php程序

    效果展示

    展示不了一点,我发现部署几天后开始变得非常卡,不知道为啥

    所以我推荐你每天定时deploy一下,会好很多

    一,注册需要的账号

    你需要注册以下账号

    • github
    • vercel
    • 一个免费或者你自己搭建的mysql数据库

    关于数据库,不推荐使用国内的免费数据库,因为vercel访问太慢了
    或许你可以尝试db4free,或者一些免费空间提供的数据库

    二,操作步骤

    1. 创建git仓库

    在github创建一个仓库,注意这个仓库需要是private的,也就是私密的仓库。然后clone到本地。下面为了方便,假设仓库名为blog

    2. 下载typecho

    下载地址:https://typecho.org/download

    3. 把typecho解压到仓库文件夹内

    此时文件应该存放在根目录

    4. 新建api文件夹,然后在api文件夹下创建index.php文件

    其中index.php文件的内容如下

    <?php
    $file= __DIR__ . '/..'.$_SERVER["PHP_SELF"];
    
    if(file_exists($file))
    {
       return false;
    }
    else
    {
        require_once __DIR__ . '/../index.php';
    }
    #echo $_SERVER["PHP_SELF"];

    5. 在仓库中创建vercel.json

    内容如下

    {
      "functions": {
        "api/index.php": {
          "runtime": "vercel-php@0.7.3"
        }
      },
      "routes": [{ "src": "/(.*)", "dest": "/api/index.php" }]
    }

    6. 在根目录创建config.inc.php

    内容如下

    <?php
    /**
     * Typecho Blog Platform
     *
     * @copyright  Copyright (c) 2008 Typecho team (http://www.typecho.org)
     * @license    GNU General Public License 2.0
     * @version    $Id$
     */
    
    /** 开启https */
    define('__TYPECHO_SECURE__',true);
    
    /** 定义根目录 */
    define('__TYPECHO_ROOT_DIR__', dirname(__FILE__));
    
    /** 定义插件目录(相对路径) */
    define('__TYPECHO_PLUGIN_DIR__', '/usr/plugins');
    
    /** 定义模板目录(相对路径) */
    define('__TYPECHO_THEME_DIR__', '/usr/themes');
    
    /** 后台路径(相对路径) */
    define('__TYPECHO_ADMIN_DIR__', '/admin/');
    
    /** 设置包含路径 */
    @set_include_path(get_include_path() . PATH_SEPARATOR .
    __TYPECHO_ROOT_DIR__ . '/var' . PATH_SEPARATOR .
    __TYPECHO_ROOT_DIR__ . __TYPECHO_PLUGIN_DIR__);
    
    /** 载入API支持 */
    require_once 'Typecho/Common.php';
    
    /** 程序初始化 */
    Typecho_Common::init();
    
    /** 定义数据库参数 */
    $db = new Typecho_Db('Pdo_Mysql', 'typecho_');
    $db->addServer(array (
      'host' => '数据库地址',
      'user' => '数据库用户',
      'password' => '数据库密码',
      'charset' => 'utf8mb4',
      'port' => '3306',
      'database' => '数据库名',
      'engine' => 'MyISAM',
    ), Typecho_Db::READ | Typecho_Db::WRITE);
    Typecho_Db::set($db);

    7. 注释掉会阻挡操作的内容

    打开根目录下的install.php文件,注释或者删除773-775行,注释的内容大概如下。

        // if (!$writeable) {
            // $errors[] = _t('上传目录无法写入, 请手动将安装目录下的 %s 目录的权限设置为可写然后继续升级', $uploadDir);
        // }

    这里如果没有删除,可能会无法初始化数据库

    8. 上传代码,在vercel中编译,注意提前绑定域名

    9. 第一次打开会报错

    提示Database Query Error。这时你需要在你的域名||vercel提供的免费域名后添加/install.php,然后按照步骤操作。

    这里如果你没有执行第7步的操作,可能会报错,建议修改之后重新提交

    三,注意事项

    1. 过长的等待时间会触发vercel报错,提示This Serverless Function has timed out. 这时你或许可以考虑更换数据库
    2. 注意看第7点
    3. 一些函数官方说支持,但是会有奇怪的问题
    4. 上传二进制文件和直接修改文件的功能就别想了,在仓库中操作吧
    5. 暂时想不到了
  • 为什么不应该在超链接中使用下划线

    一、不利于SEO

    搜索引擎会认为 aaa_bbb 是一个连词,从而识别为这是一个整体单词 aaabbb 。例如你搜索 my_site ,搜索引擎会认为你搜索了 mysite 而非 my site 。而在链接中使用 - 会让搜索引擎认为这是分词符,从而输入更多的准确的关键字。可以参考Google的说明文档

    进而,在用户进行搜索时,搜索引擎可能会忽略你的网站内容。

    二、利于分辨

    友好的内容不仅应该方便机器读取,更应该首先考虑人的感受。那么从人的角度来说为什么不应该使用下划线

    1. 下划线同样会给人一个“这是个长单词的感觉”。没有人会记住你想表达的内容。
    2. 一般的超链接的样式会设置为下划线和蓝色,如果你的链接内带有下划线,有可能会和样式产生重叠和遮挡。
    3. 如果超链接在文本中进行展示时,当你有一个比较长的链接,比如: site.com/this_is_a_very_long_link_on_my_website 。人在试图读这个链接时,眼睛会不由自主地跟随下划线移动。这似乎不太合适。

    三、约定俗成的习惯和莫名其妙的bug

    一般在计算机领域,我们在本地文件会使用下划线内容。然后上传文件后对外提供的链接就会是这样: http://site.com/file_name.txt 。但是这样会出现一个问题:在互联网传播时,浏览器内复制粘贴会将 _ 转义为 %5F ,如果服务器没有进行配置,那你的超链接的文件就会404。而且貌似很多知名公司都有这个问题
    (现在可能已经被修复)。

    四、在域名中不合法

    RFC1738RFC1035等多次投票结果的规则中对域名中出现 _ 表示禁止。也对以前申请了证书的带有下划线的域名的证书进行了回收和禁止续费。但这只是顶级域名的要求,而不是对于顶级域名下的子超链接和文件的限制。

    其实只是很久以前看过的一个博客。说的是在美国军队中导致的一些问题从而禁用了下划线,最近想到了就重新整理一下写成文章分享出来。

  • 网页程序如何正确设置用户路由

    以下是一些在网页程序中设置用户主页路由比较合理的方式及相关要点:

    基于 RESTful 风格

    路径设计

    通常可以采用类似 /users/{username} 这样的路径形式,其中 {username} 是可变的部分,代表具体的用户名。例如,若用户名为 john,那访问 /users/john 就可以跳转到对应的用户主页。这种方式清晰地体现了资源(用户)与对应的标识(用户名)的关系,符合 RESTful 规范中对资源定位的要求,方便理解和记忆,也利于前后端的分工协作以及接口的统一管理。

    还可以添加版本号在路由最前面,如 /v1/users/{username},便于后续对 API 等进行迭代升级,不同版本的路由逻辑可以独立维护,不会相互干扰。

    HTTP 方法匹配

    对于用户主页的获取(也就是查看用户主页信息),一般使用 GET 方法来请求对应的路由。比如,当浏览器发起 GET 请求到 /users/john 时,后端根据这个路由和请求方法,查询数据库中关于 john 用户的信息并返回给前端进行展示,符合 RESTful 中不同方法对应不同操作语义的原则,GET 方法专门用于获取资源这一操作场景。

    考虑用户身份验证与授权相关路由整合

    登录态验证

    • 在用户主页路由对应的处理逻辑之前,往往需要先验证用户是否已经登录。可以通过中间件来拦截请求,检查请求中携带的登录凭证(如 token 等)是否有效。比如,在很多基于 Node.js 的 Web 框架(像 Express)中,编写一个验证登录态的中间件,在路由配置里让用户主页路由先经过这个中间件,只有验证通过才能继续后续的主页数据获取和渲染流程,确保未登录用户无法直接访问用户主页,保障页面的访问安全性和隐私性。

    权限控制路由结合

    有时候用户主页可能根据用户权限展示不同内容,例如管理员用户的主页可能有更多管理功能入口。此时,路由可以配合权限控制模块,根据用户的角色(如普通用户、管理员等)来决定在加载用户主页时,返回哪些对应的模块数据和页面布局。像可以在路由处理函数中先获取用户角色信息,再依据角色从数据库中查询相应权限下的页面配置数据,以准确渲染出符合其权限的用户主页。

    动态路由参数与页面状态关联

    页面主题切换参数

    若用户主页支持切换主题(如亮色模式、暗色模式等),可以在路由中添加额外的参数来表示主题状态,比如 /users/{username}?theme=dark 表示访问 username 用户的主页且采用暗色主题模式。后端接收到这样带有参数的路由请求后,根据 theme 参数的值来调整返回给前端的页面样式相关资源,实现灵活的页面状态定制。

    分页相关参数

    当用户主页有分页展示内容(比如用户发布的文章列表分页显示等),路由中可以包含分页参数,像 /users/{username}/posts?page=2&limit=10,表示查看 username 用户的文章列表,当前是第 2 页,每页显示 10 条内容。后端根据这些参数从数据库中准确提取对应的数据返回给前端,方便用户浏览不同页面的数据内容,提升用户体验。

    路由懒加载与缓存策略配合

    懒加载实现

    对于比较复杂的用户主页,尤其是包含很多模块(如动态的个人动态展示、好友推荐等多个功能模块),可以采用路由懒加载的方式。例如在基于 Vue.js 或 React 等前端框架构建的单页面应用中,将用户主页的不同组件模块配置成懒加载形式,如 const UserHomePage = () => import (‘./UserHomePage.vue’);(Vue.js 示例),这样当用户访问到对应路由时,才会去加载对应的模块代码,减少初始加载的资源量,提高页面加载速度。

    缓存优化

    结合缓存策略,对于用户主页中一些相对静态、不常变化的数据(比如用户的基本信息介绍等),可以在浏览器端或者服务器端设置缓存机制。比如,在服务器端通过设置合适的缓存头(如 Cache-Control 等),告诉浏览器在一定时间内可以直接使用缓存的页面内容,减少重复请求,提升用户再次访问主页的响应速度,同时减轻服务器压力。

    国际化与本地化路由适配

    语言参数设置

    如果网页程序支持多语言,在用户主页路由中可以添加语言相关参数,比如 /users/{username}?lang=en 表示访问 username 用户的主页且采用英语语言环境。后端根据这个参数,加载对应的语言包来渲染页面文字内容,使得不同语言习惯的用户都能获得合适的用户主页展示效果,方便国际化拓展和满足不同地区用户的需求。

    总之,设置用户主页路由需要综合考虑多方面因素,从路由的规范、安全性、页面状态灵活度、性能优化以及多语言适配等角度出发,打造出合理且易用的路由体系。

    次级域名方案分析

    技术可行性

    从技术角度来说,是可以设置username.website.com这类次级域名(也称为子域名)路由的。在服务器配置层面,对于支持虚拟主机的 Web 服务器(如 Apache 和 Nginx),可以通过配置虚拟主机来实现子域名的指向。

    以 Nginx 为例,你需要在服务器配置文件中添加一个新的服务器块(server block)。假设你的主域名是website.com,要为用户username设置子域名路由,配置可能如下:

    server {
        listen       80;
        server_name  username.website.com;
        # 以下是实际指向的路径,例如指向用户主页的目录
        location / {
            root   /var/www/username_homepage;
            index  index.html;
        }
    }

    这就将username.website.com这个子域名请求指向了/var/www/username_homepage这个服务器上的目录,当用户访问该子域名时,服务器会从这个目录中寻找并返回相应的网页文件。

    域名系统(DNS)配置

    要使用username.website.com这样的子域名,还需要在域名系统(DNS)中进行正确的配置。你需要添加一条CNAME(规范名称)记录或者A记录(如果是直接指向IP地址)来将子域名指向你的服务器。

    如果你的网站是通过域名注册商管理的,你可以登录到域名管理控制台,在DNS设置区域添加相应的记录。例如,添加一个CNAME记录,将username.website.com指向website.com(假设website.com已经正确配置指向服务器的IP地址),或者直接添加A记录,将username.website.com指向服务器的实际IP地址。

    应用程序路由逻辑

    在网页程序内部,你需要根据请求的子域名来确定对应的路由逻辑。例如,在后端应用程序(如使用Python的Flask或Django等框架)中,需要编写代码来识别子域名部分,并根据不同的username加载相应的用户主页内容。

    在Flask中,你可以使用request对象来获取请求的子域名信息,如下所示:

       from flask import Flask, request
       app = Flask(__name__)
       @app.route('/')
       def user_homepage():
           subdomain = request.headers.get('Host').split('.')[0]
           # 根据子域名subdomain(也就是username)加载对应的用户主页内容
           # 这里只是示例,实际可能需要查询数据库等操作
           return f"Welcome to the homepage of {subdomain}"

    注意事项

    • 安全性:确保在处理子域名请求时,进行适当的安全验证。例如,防止恶意用户通过构造虚假的子域名来访问未授权的内容或者进行攻击。可以通过验证用户身份、检查子域名是否在合法的用户列表中等方式来增强安全性。
    • 性能和维护成本:使用大量的子域名可能会增加服务器配置的复杂性和维护成本。每次添加新的子域名都需要在服务器和 DNS 中进行配置,并且需要确保应用程序能够正确处理这些子域名请求。此外,过多的子域名可能会对服务器性能产生一定的影响,尤其是在处理大量并发请求时。
    • 兼容性:有些浏览器或者网络环境可能对某些子域名设置有特殊的限制或者兼容性问题。在部署使用子域名的路由之前,最好进行充分的测试,以确保在各种主流设备和浏览器上都能正常工作。
    • 一些需要保留的用户名或者分层进行路由处理。例如典型的www用户名,可能会使用户主页引向产品首页。还有比如github的security 用户,你打开他的主页就会跳转到 github.com/security 的页面。此外gitee也有类似的问题。

    所以在设置用户路由或者用户页面时,需要首先考虑到安全性,其次就是功能性,这种可能影响到内容使用和系统安全的操作,用户体验或许需要向后排一排。

  • 本地部署nexus3 搭建maven私服

    由于JFREG的一系列惊人操作,GITEE关闭maven功能,不得已,本地搭建以下maven服务。

    准备工作:JDK (如果你的设备存在JDK环境,请忽略这部分。)

    (更多…)

  • 用PHP做一个自己的访问统计

    原因

    为什么自己写

    因为在自己域下,可控&不会被常见的去广告插件屏蔽

    为什么选择PHP

    我曾经试图用CSS方法实现,奈何技术有限,且我不是专业的前端和后端。不过如果有兴趣的朋友可以看看这个文章 https://herman.bearblog.dev/how-bear-does-analytics-with-css/ 。这个作者简单介绍了自己如何使用CSS方法进行统计并计算PV之类的数据。

    且我希望是放在主题文件下可以直接运行和使用,没有想在服务端运行docker或者其他程序

    它有什么功能

    机制简单的统计,访问+1,刷新+1,如此而已

    开始

    创建数据库

    首先你需要创建数据库,如果你有数据库的前提下,请使用下面的语句新建一张这样的表:

    CREATE TABLE statistics (
        id INT AUTO_INCREMENT PRIMARY KEY,
        site_name VARCHAR(255) NOT NULL,
        visit_count BIGINT NOT NULL DEFAULT 0
    );

    这个表里只包含了一个网站地址和这个网站相对应的访问数量。它的结构大概是:

    sitename visit_count
    banzhuanriji.com 123

    然后我们初始化一下:

    INSERT INTO statistics (site_name, visit_count) VALUES ('banzhuanriji.com', 0);

    新建一行banzhuanriji.com的数据,且把默认数据(访问量)设置为0

    实现代码

    首先在你的主题目录下创建一个counter.php的文件,文件内容如下

    <?php
    $servername = "localhost";
    $username = "statistics";
    $password = "password";
    $dbname = "statistics";
    
    // 创建连接
    $conn = new mysqli($servername, $username, $password, $dbname, 3306);
    
    // 检查连接
    if ($conn->connect_error) {
        die("连接失败,请稍后再试。");
    }
    
    // 指定网站名称
    $site_name = 'banzhuanriji.com'; // 这里修改为需要统计的网站名称
    
    // 更新浏览次数
    $sql = "UPDATE statistics SET visit_count = visit_count + 1 WHERE site_name = ?";
    $stmt = $conn->prepare($sql);
    $stmt->bind_param("s", $site_name); // 绑定网站名称
    $stmt->execute();
    
    // 获取当前浏览次数
    $sql = "SELECT visit_count FROM statistics WHERE site_name = ?";
    $stmt = $conn->prepare($sql);
    $stmt->bind_param("s", $site_name); // 绑定网站名称
    $stmt->execute();
    $result = $stmt->get_result();
    $row = $result->fetch_assoc();
    $current_views = $row['visit_count'] ?? 0; // 如果没有找到,默认值为 0
    
    // 关闭连接
    $stmt->close();
    $conn->close();
    ?>
    
    <br>当前浏览次数: <?php echo htmlspecialchars($current_views); ?>

    然后你只需要在需要的地方引用counter.php即可。下面依然以final主题为示例:

    <?php if (!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
    
    <footer style="margin:50px 0px">
    
    <span id="footer-directive">
    
    <?php $this->options->addfoot() ?>
    
    </span>
    
    <span>
    
    &copy; 2024 <a href="<?php $this->options->siteUrl(); ?>"><?php $this->options->title(); ?></a>
    
    </span>
    <?php include 'counter.php'; ?>
    </footer>
    
    </body>
    
    </html>

    然后就可以实现类似卜蒜子一样的统计效果了。而且没有使用到JS,不会被去广告插件拦截。

    其它

    如果你有兴趣可以自己动手实现一下。你也可以把数据库信息替换成typecho的数据库信息,这样就避免了新操作一个数据库的逻辑,并且可以实现使用typecho的Db.php文件操作数据库。下面给一个简单的示例,具体的实现逻辑和读写权限请自行斟酌完成。

    <?php
    // 引入 Typecho 的数据库类
    require_once '/www/wwwroot/banzhuanriji.com/usr/Typecho/Db.php'; // 确保路径正确
    
    // 获取数据库连接
    $db = Typecho_Db::get();
    
    // 指定网站名称
    $site_name = 'example.com'; // 这里修改为需要统计的网站名称
    
    try {
        // 更新特定网站的浏览次数
        $db->query("UPDATE `statistics` SET `visit_count` = `visit_count` + 1 WHERE `site_name` = ?", $site_name);
    
        // 获取当前浏览次数
        $result = $db->fetchRow($db->select('visit_count')->from('statistics')->where('site_name = ?', $site_name));
        $current_views = $result['visit_count'];
    } catch (Exception $e) {
        // 处理异常
        error_log($e->getMessage());
        $current_views = 0; // 如果出错,设置为 0
    }
    ?>
    
    <div class="counter">
        <h1><?php echo htmlspecialchars($site_name); ?> 当前浏览次数: <?php echo htmlspecialchars($current_views); ?></h1>
    </div>
  • 内网穿透工具横向对比

    在网络环境中,内网穿透工具为我们提供了便捷的方式来访问内部网络资源。本文将对 cpolar、花生壳、SAKURA FRP、NATAPP、飞鸽、网云穿、闪库、内网云、快解析、nat123 和 i996 等工具进行横向对比,分析它们的优缺点。

    (更多…)

  • ubuntu使用apache2快速搭建webdav

    1. 安装apache2
    sudo apt-get install apache2

    (更多…)

  • CloudFlare提示ERR_TOO_MANY_REDIRECTS

    首先,如果你有一定的英文阅读能力和解决问题的能力,你可以参考官方文档
    https://developers.cloudflare.com/ssl/troubleshooting/too-many-redirects/#redirect-rules

    (更多…)