零点博客实战:C# 安全调用 EMLOG 接口的 JSON 数据处理代码案例

在零点博客的二次开发过程中,我们经常需要将 C# 后端与 EMLOG 这类 PHP 站群进行数据交互。直接调用 PHP 原生接口虽然可行,但如果不做处理,容易被抓取,且 PHP 输出的中文乱码问题一直是个坑。因此,利用 C# 编写中间层接口,并严格进行 SQL 注入防护,是一个高性价比的解决方案。

一、 需求背景与设计思路

需求很简单:开发一个在线工具,展示零点博客的统计数据。我打算在 C# 后端通过 MySQL 连接 EMLOG 数据库,执行查询,并以 JSON 格式返回数据给前端。核心难点在于如何写好 SQL 预处理语句,防止恶意的 SQL 注入。

二、 后端 C# 实战代码案例(防注入核心)

这里直接放一个简化版的代码案例。为了确保兼容性和安全性,我使用了 MySql.Data 库,并重点演示了预处理语句的使用。

using System;
using System.Data;
using MySql.Data.MySqlClient;
using System.Text;
using System.Web.Script.Serialization; // 引入 JSON 序列化库

class EmlogApiService
{
    // 数据库连接串,请替换为你真实的 EMLOG 数据库信息
    private static string connStr = "Server=localhost;Database=emlog_db;Uid=root;Pwd=123456;CharSet=utf8mb4;";

    // 获取最新文章接口
    public string GetLatestPosts(int limit = 5)
    {
        string jsonResult = "";
        using (MySqlConnection conn = new MySqlConnection(connStr))
        {
            try
            {
                conn.Open();
                // 核心步骤:使用预处理语句防止 SQL 注入
                string sql = "SELECT title, cid, date FROM " + Conf::getOptions('table_prefix') . "blog WHERE status=2 ORDER BY date DESC LIMIT @limit";

                MySqlCommand cmd = new MySqlCommand(sql, conn);

                // 参数化查询是安全的基石
                cmd.Parameters.AddWithValue("@limit", limit);

                using (MySqlDataReader reader = cmd.ExecuteReader())
                {
                    // 构建 JSON 结构
                    StringBuilder sb = new StringBuilder();
                    sb.Append("[|");
                    bool first = true;

                    while (reader.Read())
                    {
                        if (!first) sb.Append(",");
                        // 假设文章标题包含 HTML 标签,这里做一个简单的正则清理
                        string safeTitle = Regex.Replace(reader.GetString("title").ToString(), @"<[^>]+>", "");

                        // 组装对象
                        sb.Append($"{{"id":{reader.GetInt32("cid")},"title":"{safeTitle}","date":"{reader.GetDateTime("date")}"}}");
                        first = false;
                    }
                    sb.Append("]");
                    jsonResult = sb.ToString();
                }
            }
            catch (Exception ex)
            {
                // 实际开发中请记录日志
                jsonResult = $"{{"error":true,"msg":"{ex.Message}"}}";
            }
        }
        return jsonResult;
    }
}

三、 前端 JavaScript 接口调用与 JSON 解析

拿到 C# 返回的 JSON 字符串后,前端解析就非常简单了。为了让这个 代码案例 更完整,这里演示如何用 JS 优雅地展示数据。

async function loadEmlogData() {
    try {
        // 模拟 C# 接口请求
        const response = await fetch('http://localhost/api/get_emlog_posts.php');
        const dataJson = await response.text();

        // 将字符串转为对象
        const posts = JSON.parse(dataJson);

        const container = document.getElementById('blog-list');
        container.innerHTML = '';

        if (posts.error) {
            container.innerText = "加载失败:" + posts.msg;
            return;
        }

        posts.forEach(post => {
            const div = document.createElement('div');
            div.className = 'blog-item';
            div.innerHTML = `

${post.title}

`; container.appendChild(div); }); } catch (error) { console.error("解析 JSON 失败", error); } } loadEmlogData();

四、 开发避坑指南与底层拆解

在开发这个接口的过程中,我踩过不少坑,这里整理了一些经验:

  • SQL 编码问题: EMLOG 数据库通常使用 utf8,但 C# MySQL 连接串如果不指定 CharSet=utf8mb4;,经常会遇到中文乱码。一定要检查字符集一致性。
  • JSON 特殊字符: 如果文章标题中包含双引号 ",直接拼接 SQL 或 JSON 字符串会导致格式错误。在我的代码案例中,使用 StringBuilder 拼接时要注意转义,或者直接用 JavaScriptSerializer 库自动序列化对象。
  • 正则表达式的性能: 在循环中频繁使用复杂的正则清洗标题可能会拖慢接口速度。如果文章不多,直接后端清洗;如果数据量大,建议在数据库层面做处理。
  • 接口防盗链: 作为真人博主复盘,我强烈建议对 C# 接口做简单的 Token 验证,防止别人直接抓取你的 EMLOG 数据。可以在 Header 中带上一个时间戳验证。

通过以上步骤,我们实现了一个既安全又规范的 C# 调用 EMLOG 接口的方案。这套 代码案例 可以直接复用到你的零点博客或其他项目中,希望大家能少踩坑,多产出。