阅读视图

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

产品被拒

晚上下了班打开电脑刚坐下就看到了一封 Google 邮件,首先看到了发件人 “Chrome Web Store”,当时就心想提交审核一个多星期了,终于看到一点音信了。点开后,还没等我高兴,便看到了:

Chrome 应用商店:"EasyFill"被拒通知

解决BUG

被拒的原因非常低级,声明了但未使用的 scripting 权限。

scripting 权限是 Manifest V3 中引入的一个重要权限,主要用于动态脚本执行chrome.scripting.executeScript()和动态样式注入chrome.scripting.insertCSS()

而在EasyFill中,使用的是静态声明:

content_scripts: [
  {
    matches: ['<all_urls>'],
    js: ['content-scripts/content.js']
  }
]

删除scripting参数后,重新打包并再次向 Chrome Web Store 提交了扩展。

就这么一个小BUG,浪费了我一个星期的审核时间,太耽误事了,当时为了解决 Shadow DOM 才使用 scripting,直到现在这个问题也没有解决,希望下个版本可以解决问题

产品谍照:

EasyFill·我的信息

流水账

4月2,三月初五,周三。

和小汪初次相遇是在单位楼下,看着她从大门迎着九点钟的朝阳小跑过来,我已经心动了。从小电驴里把两盒蓝莓递给她时,装作漫不经心很随意的我双手都有些紧张得微微颤抖。

来的路上还是有点小插曲。本打算搞盒草莓尝尝,还要去零食店准备能量补品士力架,所以来的路上紧赶慢赶——经常被鹏董和纪公子批评说是出门就要蹲半小时厕所的我想着这次可得早到。结果到了两家水果店都因为太早而还没到新鲜草莓的货,只好换吃蓝莓,味道还真不错。之后就是熟悉的捡垃圾!难得遇见一位好同志愿意陪我爬山做公益。感受:好久没运动,够呛哈哈。中午吃炸鸡补充能量,下午一起去新华书店看中国地图=o=

中午两点时还请小汪陪我去趟相馆拍了张最新照片,去年也是在这一家拍的。因为我当时各类场合用的仍然还是一八年高考后的证件照,过六年了都,不能再掏出来装嫩了。今年去之前给老板发了个消息问在不在,他应该也是看见了去年聊天记录,所以我到了前台说要拍证件照后,第一句就问我说不是刚拍过了嘛。我答曰:今后每年都要更新一次。

之后的发展,就是拉着小乖陪我一起散步、一起逛街,摸黑逛公园,探索新食物,还有鄱阳湖边吹凉风……我想起了近二十年前的某天晚上,和爹娘一同在发小家里聊天玩耍,有一刹那我恍惚间感觉就像身处梦幻,周边一切都太安宁太惬意了,那个氛围至今也不能忘。有时和小乖在一起,我也会恍惚感觉好幸福呀。想起以前有一天我愣是在美梦里笑醒了,但是现在,我能紧紧握住身旁小汪的手掌心,我能把她拥入我怀中~这是来自小乖的、独属于我的真切情意。

Z-BlogPHP 中自定义 Feed 输出功能的实现与应用

image.png

在网站开发领域,为用户提供高效便捷的内容订阅途径,是提升用户体验、增强用户粘性的关键举措。在使用Z-BlogPHP搭建网站时,我们能够借助自定义PHP脚本,打造满足特定需求的Feed输出功能。接下来,本文将深入剖析feed_id.php和page_feed.php这两个脚本的功能、实现逻辑,以及基于它们所创建的 “订阅” 栏目。

feed_id.php脚本主要用于依据Z-BlogPHP中的分类$categoryId,展示对应分类下的部分内容,生成分类的Feed输出。该脚本首先引入Z-BlogPHP系统核心文件并加载系统,为后续操作奠定基础。接着从URL参数获取分类ID,对其进行有效性验证,若分类ID无效或对应分类不存在,则输出错误信息并终止脚本运行。之后设置响应头为XML格式,生成XML声明及RSS 2.0文档的相关结构,并填充频道的标题(含分类名称和博客名称)、链接(分类链接)、描述(分类简介)和语言等信息。最后通过 $zbp->GetArticleList() 方法获取指定分类下正常发布的文章列表,按发布时间倒序排列,循环输出最多10篇文章的标题、链接、描述、发布日期和唯一标识符等内容,完成 Feed 的生成。比如,访问下方URL就能获取分类ID为2的分类内容的Feed输出。

https://www.dao.js.cn/feed_id.php?id=2

page_feed.php 脚本的核心功能是通过 GetPageList 方法获取网站内所有单页的信息,并生成相应的 Feed 输出。此脚本同样先引入并加载Z-BlogPHP系统,将当前操作类型设为feed并设置XML格式的响应头。然后执行相关钩子函数,生成XML声明和RSS 2.0文档的起始结构,填充频道的标题(含 “所有单页” 和博客名称)、链接(博客主页链接)、描述(所有单页的 RSS Feed)及语言等信息。再利用$zbp->GetPageList()方法获取所有单页列表,循环输出每个页面的标题、链接、描述(页面简介)、发布日期和唯一标识符等信息,最后结束XML结构并执行相应钩子函数。用户通过访问下方URL,便能获取所有的Feed输出。

https://www.dao.js.cn/page_feed.php

在完成feed_id.php和page_feed.php脚本的编写后,我们进一步创建了 “订阅” 栏目。用户访问 https://www.dao.js.cn/feed 即可进入该栏目,在此查看不同分类的内容Feed以及所有单页的Feed,及时掌握网站的最新动态。

通过对feed_id.php和page_feed.php脚本的精心开发与应用,我们在Z-BlogPHP网站中成功实现了自定义 Feed 输出功能,并搭建起 “订阅” 栏目。这不仅优化了网站的内容展示效果,还为用户提供了更为便捷的内容获取方式,有助于提升用户的留存率与活跃度。在今后的网站开发和维护中,我们还可依据实际需求,对这些脚本进行优化和拓展,以适应不断变化的业务场景。

需要feed_id.php和page_feed.php文件的,请通过“联系”栏目与我取得联系。feed页面模板如下:

    <h2>总体订阅</h2>                            
    <div class="category-wrapper">
        <a target="_blank" href="/feed.php" class="dingyue" title="南蛮子懋和博客默认订阅">
            <div class="dingyuetext">
                <div class="dingyuexl">默认订阅</div>
            </div>
            <i class="bi bi-rss"></i>
        </a>
        <a target="_blank" href="/page_feed.php" class="dingyue" title="南蛮子懋和博客单页订阅">
            <div class="dingyuetext">
                <div class="dingyuexl">单页订阅</div>
            </div>
            <i class="bi bi-rss"></i>
        </a>
    </div>
    <h2>分类订阅</h2>
    <div class="category-wrapper">
        {php}
        global $zbp;
        $categories = $zbp->GetCategoryList();
        foreach ($categories as $category) {
            if ($category->ID != 1) {
                $feed_url = 'feed_id.php?id='.$category->ID;
        {/php}
        <a target="_blank" href="{php}echo $feed_url;{/php}" class="dingyue" title="{php}echo $category->Intro;{/php}">
            <div class="dingyuetext">
                <div class="dingyuexl">{php}echo $category->Name;{/php}</div>
            </div>
            <i class="bi bi-rss"></i>
        </a>
        {php}
            }
        }
        {/php}
    </div>

依照Z-BlogPHP创建自定义页面方式,再合适的地方插入即可。需要feed样式的,可以自行f12复制,也可以向我索取,具体展示渲染效果如下:

https://www.dao.js.cn/feed

巧用张洪HeoMusic思路构建了我的“歌单”

image.png

在音乐爱好者的世界里,拥有一个能自由听取的个性化歌单是许多人的梦想。为了实现这一目标,我借鉴了张洪 HeoMusic 的思路,成功搭建了属于自己的歌单页面。

https://blog.zhheo.com/p/45699256.html

张洪 HeoMusic 的思路为整个项目提供了关键的指引方向,其独特的架构理念和对音乐播放系统的理解,成为我搭建歌单页面的基石。在这个基础上,我对Meting.min.js进行了二次更改,这一举措极大地拓展了音乐获取的自由度。通过对代码的精细调整,我可以更灵活地从不同渠道获取心仪的音乐,让歌单内容更加丰富多样。值得注意的是因为跨域等问题,我们需要自己构建、或者反代一个API,因为版权原因,暂不提供思路,我是使用的injahow/meting-api使用cloudflare搭建的API。

为了实现多id合并并打乱顺序输出json,我对Meting.min.js进行了下述修改(尊重著作权,console.log输出版权信息)

class MetingJSElement extends HTMLElement {
    constructor() {
        super();
        this._initialized = false;
    }

    connectedCallback() {
        if (window.APlayer && window.fetch &&!this._initialized) {
            this._init();
            this._parse();
            this._initialized = true;
        }
    }

    disconnectedCallback() {
        if (!this.lock && this.aplayer) {
            this.aplayer.destroy();
        }
    }

    _camelize(str) {
        return str
          .replace(/^[_.\- ]+/, '')
          .toLowerCase()
          .replace(/[_.\- ]+(\w|$)/g, (m, p1) => p1.toUpperCase());
    }

    _init() {
        let config = {};
        for (let i = 0; i < this.attributes.length; i += 1) {
            config[this._camelize(this.attributes[i].name)] = this.attributes[i].value;
        }
        let keys = [
            'server', 'type', 'id', 'api', 'auth',
            'auto', 'lock',
            'name', 'title', 'artist', 'author', 'url', 'cover', 'pic', 'lyric', 'lrc',
        ];
        this.meta = {};
        for (let key of keys) {
            this.meta[key] = config[key];
            delete config[key];
        }
        this.config = config;

        this.api = this.meta.api || window.meting_api || 'https://xxx.xxx.xxx/?server=:server&type=:type&id=:id&r=:r';
        if (this.meta.auto) this._parse_link();

        // 支持多个 ID,将 id 属性按逗号分割成数组
        this.meta.ids = this.meta.id.split(',');
    }

    _parse_link() {
        let rules = [
            ['music.163.com.*song.*id=(\\d+)', 'netease', 'song'],
            ['music.163.com.*album.*id=(\\d+)', 'netease', 'album'],
            ['music.163.com.*artist.*id=(\\d+)', 'netease', 'artist'],
            ['music.163.com.*playlist.*id=(\\d+)', 'netease', 'playlist'],
            ['music.163.com.*discover/toplist.*id=(\\d+)', 'netease', 'playlist'],
            ['y.qq.com.*song/(\\w+).html', 'tencent', 'song'],
            ['y.qq.com.*album/(\\w+).html', 'tencent', 'album'],
            ['y.qq.com.*singer/(\\w+).html', 'tencent', 'artist'],
            ['y.qq.com.*playsquare/(\\w+).html', 'tencent', 'playlist'],
            ['y.qq.com.*playlist/(\\w+).html', 'tencent', 'playlist'],
            ['xiami.com.*song/(\\w+)', 'xiami', 'song'],
            ['xiami.com.*album/(\\w+)', 'xiami', 'album'],
            ['xiami.com.*artist/(\\w+)', 'xiami', 'artist'],
            ['xiami.com.*collect/(\\w+)', 'xiami', 'playlist'],
        ];

        for (let rule of rules) {
            let patt = new RegExp(rule[0]);
            let res = patt.exec(this.meta.auto);
            if (res!== null) {
                this.meta.server = rule[1];
                this.meta.type = rule[2];
                this.meta.id = res[1];
                return;
            }
        }
    }

    async _parse() {
        if (this.meta.url) {
            let result = {
                name: this.meta.name || this.meta.title || 'Audio name',
                artist: this.meta.artist || this.meta.author || 'Audio artist',
                url: this.meta.url,
                cover: this.meta.cover || this.meta.pic,
                lrc: this.meta.lrc || this.meta.lyric || '',
                type: this.meta.type || 'auto',
            };
            if (!result.lrc) {
                this.meta.lrcType = 0;
            }
            if (this.innerText) {
                result.lrc = this.innerText;
                this.meta.lrcType = 2;
            }
            this._loadPlayer([result]);
            return;
        }

        const allMusicData = [];
        for (const id of this.meta.ids) {
            let url = this.api
              .replace(':server', this.meta.server)
              .replace(':type', this.meta.type)
              .replace(':id', id)
              .replace(':auth', this.meta.auth)
              .replace(':r', Math.random());

            try {
                const res = await fetch(url);
                if (!res.ok) {
                    throw new Error(`HTTP error! status: ${res.status}`);
                }
                const text = await res.text();
                const result = JSON.parse(text);
                if (Array.isArray(result)) {
                    allMusicData.push(...result);
                } else {
                    console.error(`Data for ID ${id} is not an array:`, result);
                }
            } catch (error) {
                console.error(`Fetch error for ID ${id}:`, error);
            }
        }

        // 对获取到的所有音乐数据进行随机排序
        const shuffledMusicData = this._shuffleArray(allMusicData);

        this._loadPlayer(shuffledMusicData);
    }

    _shuffleArray(array) {
        for (let i = array.length - 1; i > 0; i--) {
            const j = Math.floor(Math.random() * (i + 1));
            [array[i], array[j]] = [array[j], array[i]];
        }
        return array;
    }

    _loadPlayer(data) {
        let defaultOption = {
            audio: data,
            mutex: true,
            lrcType: this.meta.lrcType || 3,
            storageName: 'metingjs'
        };

        if (!data.length) return;

        let options = {
            ...defaultOption,
            ...this.config,
        };
        for (let optkey in options) {
            if (options[optkey] === 'true' || options[optkey] === 'false') {
                options[optkey] = (options[optkey] === 'true');
            }
        }

        let div = document.createElement('div');
        options.container = div;
        this.appendChild(div);

        this.aplayer = new APlayer(options);
    }
}

console.log('\n %c MetingJS v2.0.1 %c https://github.com/metowolf/MetingJS \n', 'color: #fadfa3; background: #030307; padding:5px 0;', 'background: #fadfa3; padding:5px 0;');

if (window.customElements &&!window.customElements.get('meting-js')) {
    window.MetingJSElement = MetingJSElement;
    window.customElements.define('meting-js', MetingJSElement);
}

然而,在享受技术带来的便利时,我们绝不能忽视著作权的重要性。每一首音乐都是创作者的心血结晶,我们应当在合法合规的前提下使用这些作品,确保对知识产权的尊重。

在前端渲染方面,我选择了APlayer播放器。APlayer以其简洁美观的界面和强大的功能,为用户带来了优质的播放体验。它能够流畅地展示歌曲信息、控制播放进度,并且支持多种主题自定义,使歌单页面在功能性和美观性上达到了较好的平衡。

在前端仅需要随便往哪里插入下列代码即可(我是获取的“我收藏的歌单”下列的歌单,id是什么,需要自行理解,我尊重各站版权)

<link rel="stylesheet" href="/sucai/APlayer/APlayer.min.css">
<script src="/sucai/APlayer/APlayer.min.js"></script>
<script src="/sucai/APlayer/Meting.min.js"></script>
<meting-js server="netease" type="playlist" id="6948853317,326934130,446132364,978446985,2286543721,7235859079" autoplay="true" order="list" preload="auto" list-max-height="100vh"></meting-js>

通过这次实践,我不仅实现了歌单听取自由化的目标,还在技术运用和版权意识上有了更深的体会。希望我的经验能为其他音乐爱好者和开发者提供一些参考,共同打造更加优质、合法的音乐环境。

https://www.dao.js.cn/music

关于本站外链处理的思考与行动

一、缘起

在日常维护网站的过程中,一个细节问题引起了我的注意。一直以来,我都十分珍视与其他站点的友好合作关系,通过友情链接、联盟推广等方式,努力为用户拓展更多优质的信息渠道。然而,近期我在对网站进行深入检查时发现,博客中许多站外跳转链接,包括友链等,都没有正确设置 rel 标签。其实,由于一些不可控因素,之前我为所有站外跳转链接设置了中间跳转机制,本意是为了更好地管理和保障用户的浏览安全。但在这个过程中,却疏忽了 rel 标签的设置。

https://www.dao.js.cn/new/2025030511627.shtml

经过对友链的逐一排查,我发现目前共有 58 个友链站点。其中 41 个站点对出站链接(不限于友链)的 a 标签设置了 rel="noopener noreferrer nofollow",这体现了他们对网站 SEO 优化和链接管理的重视。有 5 个站点采用了转译的 golink 跳转方式处理出站链接,而 “爱写书” 站点则完全没有设置 target 和 rel 标签。其余站点虽设置了 target 跳转,但 rel 标签方面存在缺失。

对于友情链接设置 rel 标签,我内心一直有所顾虑。毕竟友情链接是网站之间友好交流的桥梁,设置 rel="noopener noreferrer nofollow" 可能会在一定程度上影响到友链站点的权益,感觉对友链朋友不够友好。尤其是 “爱写书” 站点,没有对我的站点链接做过多限制,这种信任让我很是感激。但从网站自身的 SEO 角度出发,缺失 rel 标签可能会导致 SEO 权重外流,影响网站在搜索引擎中的表现。

在这种纠结的心态下,我经过反复思考,最终决定还是要对网站的外链进行合理处理,以平衡网站自身发展和与友站的关系。

二、思考

从 SEO 的专业知识来讲,rel 标签的正确设置对于网站的权重分配和安全性至关重要。rel="noopener noreferrer nofollow" 这组属性,一方面可以有效防止搜索引擎将本站权重过多传递到外部链接,保障自身网站在搜索排名中的优势;另一方面,也能避免用户因误点恶意外链而带来的潜在风险。

然而,在实际操作中,要对全站的外链进行统一处理并非易事。网站的外链数量众多,来源复杂,涵盖了友链、广告链接、合作推广链接等多种类型。不同类型的外链,其功能和目的各异,处理方式也不能一概而论。而且,在处理外链时,还必须充分考虑用户体验。如果处理不当,可能会导致部分链接无法正常跳转,或者给用户的浏览过程带来不必要的困扰。经过慎重考虑,我认为对全站非 window.location.hostname 的 a 标签 url 施行强制 rel="noopener noreferrer nofollow" 处理是较为合适的方案。

这样既能最大程度地保障网站的 SEO 效果,又不会对用户的正常浏览造成严重影响。对于站内链接,用户可以自由访问;而对于站外链接,设置 rel 标签则是在保护网站自身利益的同时,也提醒用户谨慎对待外部链接。

三、实现

为了实现对全站外链的自动化处理,我借助了 JavaScript 技术。以下是具体的代码实现:

document.addEventListener('DOMContentLoaded', function () {
    const currentDomain = window.location.hostname;

    // 处理所有现有的 <a> 标签
    const allLinks = document.getElementsByTagName('a');
    for (let i = 0; i < allLinks.length; i++) {
        const link = allLinks[i];
        const href = link.href.trim();
        if (isValidExternalLink(href, currentDomain)) {
            link.setAttribute('rel', 'noopener noreferrer nofollow');
        }
    }

    // 创建一个 MutationObserver 实例来监听 DOM 变化
    const observer = new MutationObserver((mutationsList) => {
        for (const mutation of mutationsList) {
            if (mutation.type === 'childList') {
                // 遍历新增的节点
                for (const addedNode of mutation.addedNodes) {
                    if (addedNode.nodeName === 'A') {
                        const link = addedNode;
                        const href = link.href.trim();
                        if (isValidExternalLink(href, currentDomain)) {
                            link.setAttribute('rel', 'noopener noreferrer nofollow');
                        }
                    } else if (addedNode.querySelectorAll) {
                        // 检查新增节点的子节点中是否有 <a> 标签
                        const newLinks = addedNode.querySelectorAll('a');
                        for (const newLink of newLinks) {
                            const href = newLink.href.trim();
                            if (isValidExternalLink(href, currentDomain)) {
                                newLink.setAttribute('rel', 'noopener noreferrer nofollow');
                            }
                        }
                    }
                }
            } else if (mutation.type === 'attributes' && mutation.attributeName === 'href') {
                const link = mutation.target;
                const href = link.href.trim();
                if (isValidExternalLink(href, currentDomain)) {
                    link.setAttribute('rel', 'noopener noreferrer nofollow');
                }
            }
        }
    });

    // 配置 MutationObserver 监听的选项
    const config = { childList: true, subtree: true, attributes: true, attributeFilter: ['href'] };
    // 开始监听 document.body 及其子节点的变化
    observer.observe(document.body, config);

    function isValidExternalLink(href, currentDomain) {
        if (!href || href.startsWith('#') || href.startsWith('javascript:')) {
            return false;
        }
        try {
            const url = new URL(href);
            return url.hostname!== currentDomain;
        } catch (error) {
            return false;
        }
    }
});

这段代码的逻辑是:当页面加载完成(DOMContentLoaded 事件触发)时,获取当前页面的域名 currentDomain。然后遍历页面上所有的 <a> 标签,获取每个标签的 href 属性并进行修剪。通过 isValidExternalLink 函数判断该链接是否为有效的外部链接,如果是,则为其添加 rel="noopener noreferrer nofollow" 属性。同时,利用 MutationObserver 监听 DOM 的变化。当检测到有新节点添加(childList 类型变化)或 <a> 标签的 href 属性改变(attributes 类型变化且 attributeName 为 href)时,对新的或属性变化的 <a> 标签执行相同的检查和处理操作。

在代码编写完成后,我进行了严格的测试。先在本地开发环境中模拟各种页面情况和外链类型,确保代码能准确识别和处理外部链接。随后在生产环境中选取部分页面进行试点,观察实际运行效果并及时调整,最终保证代码能够稳定、有效地运行。

四、效果

image.png

经过对全站外链的处理,取得了较为显著的效果。从 SEO 方面来看,正确设置 rel 标签后,有效避免了 SEO 权重外流的问题。之前由于很多外链未设置 rel 标签,搜索引擎在抓取页面时可能会将部分权重传递到外部,影响网站自身排名。现在,搜索引擎能够更准确地处理外链,将权重更多地集中在站内页面,有助于提升网站在搜索结果中的整体排名。

在用户体验方面,虽然对外部链接设置了 rel 标签,但由于处理方式合理,并未对用户的正常浏览和跳转造成明显阻碍。用户依然可以自由点击外部链接,同时也在一定程度上提高了浏览的安全性,减少了恶意链接带来的潜在风险。此外,通过这次对外链的全面梳理和处理,我对网站的链接结构有了更清晰的认识。发现并清理了一些无效链接和重复链接,进一步优化了网站的性能和稳定性,为用户提供了更优质的浏览体验。

当然,SEO 优化是一个持续的过程,外链处理只是其中的一部分。未来,我会继续关注网站的 SEO 效果,不断优化和调整策略。同时,也会更加注重与友链站点的沟通与合作,在保障自身网站发展的前提下,维护好与友站的友好关系,共同促进互联网生态的健康发展。

思路来源于

https://blog.hslzz.cn/20250305191500.html

巧用泽泽社长NiceMapMarker思路构建我的“足迹”

image.png

最近我被 “足迹” 功能深深吸引住了,起因是逛了好多博客,发现人家都有这么个有意思的功能,能在地图上标记去过的地方,分享自己的旅程。这可把我馋坏了,心心念念着自己的博客也得安排上。为这事儿,我晚上翻来覆去,脑子里全是怎么实现 “足迹” 功能,根本睡不着觉,辗转反侧、寤寐思服、夜不能寐,满心满眼就只有这一件事。

今天总算是下定决心开始动手了,找来找去,发现泽泽社长的 NiceMapMarker 插件简直就是为我量身定制的!它能基于腾讯地图 API 和百度地图 API 实现地图多地点标记,这不就是我一直想要的嘛!

https://store.typecho.work/archives/NiceMapMarker-typecho-plugin.html

我赶紧打开插件介绍页面,仔仔细细研究起来。这一看,发现使用前准备工作还不少。首先得去腾讯地图开放平台和百度地图开放平台申请开发者账号。腾讯那边登录账号新建应用,选浏览器端,建好后能拿到应用 key;百度这边类似,新建应用拿到 AK,然后都填到插件设置里。这一步虽说有点繁琐,但难不倒我,按部就班地操作,很快就搞定了。

https://lbs.qq.com/getPoint/

接着就是查经纬度,用哪个平台就在哪个平台查。腾讯地图在指定的网址查,百度地图也有对应的查询页面。我一边查,一边感慨这细节还挺多,不过每完成一步,离实现 “足迹” 功能就更近一步,心里那叫一个兴奋。

设置参数的时候也有点小挑战。它可以用zoom参数设置地图缩放,默认是 5,还能用height参数设置地图组件在文章里显示的高度。一开始,我设置的参数没达到预期效果,地图不是缩放得不合适,就是显示高度不对。好在我多试了几次,不断调整,总算是让地图显示得像模像样了。

在文章里按照格式书写标记信息的时候,我又遇到了点小麻烦。超链接和图片链接的填写得格外注意,有一次因为少写了个符号,怎么都显示不对。不过,经过反复检查和修改,最终还是成功实现了!看着地图上一个个标记着我 “足迹” 的点,心里别提多有成就感了。

https://www.dao.js.cn/zuji

现在,我的博客 “足迹” 功能算是初步完成了。虽然过程中遇到了不少问题,但好在都一一解决了。接下来,我打算再优化优化,比如多找些好看的图片当标记,让 “足迹” 页面更美观。今天的成果让我对后续的开发充满了信心,期待能给博客带来更多有趣的功能!


把握当下,享受生活

深夜看到群友转发的诀别博客时,我盯着屏幕感到毛骨悚然,脊背发凉。 回想自己走出抑郁状态的过程,实际上只是找到了不能死的理由。 小学的梦想是做一个探索文明边界的科学家,那时的我怎会想到,初中生活已悄然埋下抑郁的伏笔,直到中考前撞上虚无主义的墙:百年后不过尘归尘,此刻煎熬有何意义? 走出相对抑郁的状态源

Folo 认证功能反成漏洞?警惕 RSS 订阅源所有权被恶意盗取风险

Folo 是什么 Folo(曾用名 Follow)是一个多平台信息流订阅软件(包括 RSS),结合了 Web3 功能(所用 Token 叫 $POWER,比特币就是一种 Token)。 在这个软件中,你可以通过 $POWER 打赏订阅源,如果有人认证了这个订阅源,就可以获得你打赏的 $POWER。打

佳能R50和索尼ZV-E10Ⅱ,最终6120块选了ZV-E10Ⅱ

一直想要一个轻巧方便携带的相机,主要用来练手,出门拍拍花草山水之类的。看了佳能R50和索尼ZV-E10Ⅱ,都符合我的要求。

本打算买个佳能R50,以后能无缝衔接,毕竟佳能给我的感觉十分好。又看了索尼ZV-E10Ⅱ,感觉这个挺好看的尤其是白色。

总结一下我眼中佳能R50与ZV-E10Ⅱ的一些区别:

设备/功能佳能R50ZV-E10Ⅱ
取景器电子取景器
对焦速度尚可相对稍快
视频拍摄尚可相对较好
套机镜头焦段18-45mm16-50mm
套机镜头调焦手动调焦手动+电动调焦
人像拍摄面部皮肤自然面部皮肤稍白

这两个相机,最终选了索尼ZV-E10Ⅱ,到店那样机把玩试试,总体感觉可以。国补后6120元,送了相机包、屏幕钢化膜、相机套、充电器。

刚开始冲着白色去的,因为白色外观视觉效果十分抢眼,很好看。当我看到样机外观的小瑕疵时决定买黑色,因为这些小瑕疵在白色机壳上十分明显,黑色却看不出这样的瑕疵。这点瑕疵不影响功能,但作为二手机出售时会影响价格。

又一个可能吃灰的设备到手,相机到手还有其他东西要买,偏光镜、滤镜、补光灯、镜头。还好索尼的镜头比较多,价格适中,以后有需要了再添置。

修整自行车,骑行打卡天马山射电望远镜。37.07公里,均速20.14km/h

很久没出去骑车了,把自行车推出来修整一下,调整车把,后拨变速器,后轮辐条。抖音视频现学现用,虽然原理简单,但是要调整到理想的状态实在太难。最终后变速器还是会跳档,五档直接跳到七档,再减一档才能到六档。后轮辐条调整了很长时间,虽然好了一些,但是还有稍许偏摆。

下午阳光正好,适合出去骑车。穿上冲锋衣,戴好头盔,特意把心率带也穿戴好。漫无目的的骑车,计划骑40公里左右,均速20左右,当做适应性骑车。毕竟很久没有长距离骑行了。

漫无目的的骑车,着实无聊。现在方向往西,各个打卡点开始在脑海中浮现,哪些地点在我的骑行范围之内。首先想到了天马射电望远镜,看好路线,去那里看看。

天马射电天文望远镜
上海市松江区九江公路1703号

途径佘天昆公路,是一条很适合骑行的公路。不是主干道,没有什么红绿灯,来往车辆比较少,虽然路面不宽,但平实的路面不颠簸。

到天马射电望远镜附近,围着望远镜寻找最佳机位。每路过一种可能,停下开拍照,再找下一个机位并拍照。围着望远镜顺时针转了一圈,最终找到了最佳机位,拍照打卡。

自行车充当模特:

广角镜头下的射电望远镜:

里程37.07km
运动均速20.14km/h
全程均速14.31km/h
最快速度28.41km/h
运动时间1:50:27
全程时间2:35:28
累计上升108m
累计下降113m
最大心率148bpm
平均心率132bpm
最大踏频127rpm
平均踏频76rpm

共骑行37.07公里,总用时2小时35分钟,运动时间1小时50分钟,时间和里程在计划之内。

虽然这次心率数据正常,但是明显感到心跳的厉害。比起年前体能下降不少,日后还得慢慢恢复。多做有氧骑行,保持好心率。

DeepSeek热度不减,尝试用AI给个人博客起名

DeepSeek铺天盖地的消息,不仅仅是科技公司部署或接入了DeepSeek,很多政企也接入了DeepSeek,如今有这番景象着实不易。曾经抵制AI的人们也开始重新审视AI,DeepSeek在国内显然成了AI的代名词。

如果把AI当工具用来提高效率,或用来增长知识,或提高认知,是不错的选择。

既然都说DeepSeek好,那我也下载试试。但是我并不知道用DeepSeek做什么事情,我的工作不需要,我的生活不需要。没有需求就创造需求,试试个人博客起名。

我尝试把域名feng.pub作为元素,让DeepSeek起名。

输入:

深入思考,给个人博客起名。提示博客主要内容为记录生活,见闻感想;博客域名:feng.pub;个人名字里有“锋”字,可以使用同音字。要求:简约、文艺、治愈。

思考过程

好的,用户需要给个人博客起名,主要记录生活见闻和感想,域名是feng.pub,名字里有“锋”字,可以用同音字。要求简约、文艺、治愈。之前已经生成过两次类似的列表,现在需要更深入思考。

首先,回顾之前的回复,用户可能希望名字既有“锋”的谐音,又融入自然元素,保持简约和治愈的感觉。之前的建议用了风、枫、逢、峰等同音字,搭配自然意象如光、溪、晴等,结构多为三词组合,比如“风檐札记”、“缝光手帖”等。

现在用户要求深入思考,可能需要更注重名字的深层含义和与个人博客内容的契合度。考虑到博客是记录生活,名字应该传达温暖、宁静和积极向上的感觉,同时保持简洁易记。

需要进一步分析用户可能的潜在需求。用户可能希望名字不仅好听,还要有独特的个性,避免过于常见。同时,域名是feng.pub,所以名字的拼音或英文缩写最好能与之呼应,增强品牌一致性。

考虑到“锋”的同音字,除了之前用过的,还可以考虑“丰”、“封”、“烽”等,但需要符合治愈的主题。例如“丰”可能带来丰收、丰富的感觉,但需要结合自然元素。

另外,结构上可能需要更简化,比如两词组合,或者更短的名称,同时保持文艺感。例如“风迹”或“锋语”,但需要检查是否已有类似博客名,避免重复。

还要注意名字的视觉效果,书写时是否美观,是否有对应的意象可以用于Logo设计。比如“檐下光”可以联想到屋檐下的阳光,适合温暖的视觉设计。

可能还需要考虑名字的扩展性,是否容易衍生出系列内容或标签,比如“札记”、“手帖”等后缀,方便分类。

最后,确保每个名字都符合简约、文艺、治愈的要求,同时巧妙融入“锋”的谐音,并与feng.pub域名形成关联。

输出:

基于深度语义挖掘与个人品牌塑造的博客命名方案,结合「锋」字内涵与feng.pub域名的声韵特质:


核心意象解构

「锋」字三重隐喻
① 锐度:生活观察的敏锐视角
② 方向:记录轨迹的持续性
③ 光芒:治愈能量的折射点

域名关联

“feng”可延伸为「风动」(动态记录)、「缝制」(故事编织)、「丰盈」(精神沉淀)三重意境层


精选命名(附深度解析)

1.【檐锋集】

  • 屋檐滴水塑造石锋的自然意象,隐喻时间沉淀的力量
  • 短音节结构(yán fēng)与域名feng.pub形成音阶呼应
  • 视觉联想:青瓦水痕插画+极细衬线字体

2.【沨迹】

  • “沨”为水流声的古字,暗合”锋”的发音与记录的本质
  • 单字「迹」浓缩了见闻轨迹与心灵印记的双重含义
  • 适合做水墨流动感的动态LOGO

3.【苔间锋】

  • 微小苔藓与锐利锋芒的戏剧性对比,象征平凡生活中的深刻洞察
  • 三词结构形成「自然物+空间介词+核心字」的黄金比例
  • 色彩方案:苔藓绿+亚麻白治愈系搭配

4.【锋物志】

  • “物”字承载器物美学与万物有灵哲学,强化记录厚度
  • 名称与域名形成「feng-wu-zhi」的韵律节奏
  • 可延伸出「锋物日历」「锋物图谱」等子栏目

5.【光隙集】

  • 用”锋”的锐利感切割出光明缝隙,构建创伤治愈隐喻
  • 名称自带光影变化的动态想象,适配多形态版式设计
  • 英文副标建议:”Through the Cracks”

命名体系构建逻辑

1. 声韵锚点

所有名称均保留”fēng”的发音内核,通过古汉字(沨/葑)、自然物(苔/檐)、抽象概念(隙/迹)实现变异演绎

2.治愈符号学

  • 材质符号:青苔/木纹/麻布等自然肌理
  • 光影符号:晨昏线/漏光/水波折射
  • 动作符号:拾/缝/触等低饱和动词

3.品牌延伸性

名称本身可拆解为视觉标识(如「苔间锋」分解为苔藓图案+匕首状书签图标),同时预留内容栏目化空间(XX手记/XX图谱/XX切片)


终极推荐方案

「沨迹 | 锋的治愈棱镜」

  • 核心价值:将生活见闻通过“锋”的棱镜这是出光谱般的治愈能量
  • 视觉系统:用不规则多边形切割水纹图案,每个切面呈现不同生活场景
  • 内容架构:光之痕(深刻事件)/ 沨之声(日常絮语) / 苔之书(微小确幸)

此命名既保留个人印记,又将博客转化为具有光学隐喻的精神容器,实现简约表达与深层意象的平衡。

“风迹”、“锋语”比较简约,另外5个名字也比较适合,都能与域名feng.pub契合。如果早点用上AI,也许我的博客就不叫“阿锋的小宇宙”了。

2025年AI应用元年,你用DeepSeek了吗?

虽然DeepSeek官方app总提示服务器繁忙,第三方平台部署的DeepSeek满血版也是不错的选择。下载了「腾讯元宝」,可以在HunyuanDeepSeek之间切换,这一点相当满意。

普通人开始使用AI了,而且是免费试用,这要感谢DeepSeek做出成就。

「BlogWe」啥时候改版了,个人独立博客越来越好

才发现「BlogWe」改版了,但不知道是啥时候改版的,翻了翻BlogWe的关于页面发现了这样的记录:

  • 2024.03.14 博客我们在沉寂了两年之后重新上线
  • 2024.04.08 新收录的博客头像采用gravatar国内镜像直连
  • 2024.11.13 优化代码,解决html错误,更换为独立IP主机

虽然不清楚「博客我们」具体什么时候更新的样式,但这次改版让我眼前一亮。「BlogWe」的审美在线,页面深邃,动漫形象的背景的地球仪有探索和冒险精神。

独立博客不是单独的个体,我们通过各种各样的方式联系在一起。「BlogWe」2020年收录的博客数量就已经达到500个。做独立博客的用户很多,随着服务器成本的降低独立博客的数量会越来越多,独立博客的类型也会更加丰富,而生活类博客更为突显。

我们不仅写博客也看博客,不为盈利的博客有很奇特的吸引力。

在互联网的广阔天地,从容不迫得展示自己,表达观点,或进行叙事,或记录见闻及感受。独立博客可以随时开启或关闭评论、订阅权限,数据可以自己掌控。虽然有些博文比不上公众平台那里的文章抓人眼球,但是在尽可能准确得表达自己的过程中不断进步,使我们所展示的内容更加清晰有结构有主题。正因为我们在文字表达方面的进步,使得独立博客的阅读环境越来越好。

博客导航、RSS聚合,正是这些平台使我们更加紧密的联系在一起。但这些平台大多不盈利,为爱发电的同时为博友默默地做着贡献。


独立博客导航、RSS聚合、综合社区

个站商店
一个精致的,带社交元素的个人网站发布平台,博客收录网站
https://storeweb.cn/

博客圈
致力于个人独立博客博客圈
https://bokequan.cn/

博客录
博客收录展示平台
https://boke.lu/

博客我们 BlogWe
做更好的个人博客导航网站
https://blogwe.com/

十年之约
即从加入这个活动起,我们的博客十年不关闭,保持更新和活力!
https://www.foreverblog.cn/

博客志
优秀个人独立博客导航
http://www.jetli.com.cn/

中文博客列表导航
尝试链接几乎所有的中文博客
https://zhblogs.ohyee.cc/

BlogFinder
发现优秀的个人博客
https://bf.zzxworld.com/

笔墨迹
致力于发掘和分享”优秀个人独立博客”
https://blogscn.fun/

博友圈
博客人的朋友圈
https://www.boyouquan.com/

博客说
个人博客站点聚合
https://blogtalk.org/

BlogsClub 博客俱乐部
我们的初衷是通过BlogsClub打造一个独立的个人博客集结地
https://www.blogsclub.org/

OurBlogs 我们的博客
我们的博客,致敬每一个坚持写博客的人
https://ourblo.gs/

Blog114
汇优秀博客 交天下朋友 致敬bloger
https://blog114.com/

博客驿站
发现新博客认识新朋友
https://www.bloginn.vip/

开往
友链接力
https://www.travellings.cn/

萌国ICP备案
萌ICP备 纯属萌友网站联萌!
https://icp.gov.moe/

家随时间慢慢改变,但归家之心未变

80年代父母因为生计离开老家镇平到义马矿区工作,没想到在义马呆了几十年。千秋矿、常村矿、跃进矿、北露天,小时候的我耳朵里几乎是矿上的事情。

爸妈本想在义马干几年赚点钱回老家生活,虽然后来在老家盖了瓦房,但是几乎没住过。姐姐、哥哥和我都在义马上学,自从我上了初中,回老家的次数更少了。目前爸妈在义马生活,老家的房子四爹家住着。老爸说,如果当年不出来,不知道现在是啥景。

在老家的二姑、二爹最为切切。近年来回老家,家里亲戚希望爸妈能回老家生活,大家在一起热热闹闹的。回老家生活得把房子修整一下,这谈何容易。

老爸时常念叨爷爷的坟,说清明的时候要回去烧纸。

小时的印象中,我回镇平老家的次数非常少,最长一次是某个暑假,在田野间戏耍了一个夏天,采野果、抓爬蚱、追蝴蝶。还记得那时跟父母回老家,睡过上下铺的大巴,也挤过无法站立的火车。

如今我对同事说回老家,一般指的是父母在的义马。

我也因为生计到上海工作,但是与父母那时的工作有天壤之别。我做不到以厂为家并信奉公司能给予一切。扎根上海实在太难,想要得到房子还是户口并非易事。虽然上海没有我的家,但是父母在的地方正是我的家。而我也像当年的父母一样,无论再难也要回家看看。

近两年春节回家及返程都不是很方便,火车票难抢,高速拥堵。但是归家的心毋庸置疑,两千里路再难也要把家归。吃一口热饭喝一口热汤,体会那熟悉的味道;转转商场逛逛老街,家在的地方也变得越来越好了。归家在此刻具象化了。

二〇二五年一月总结,新年盼归家生活照旧过

新一年的开始没有给自己打鸡血,而是顺其自然,也要认清今夕是何岁月。

今年1月底过年,早早开始盼着回家。爸妈也时常询问啥时候放假,啥时候回去,啥时候买票,火车票好买不好。而我也在计划提前请几天假。

人们常说,父母在的地方是家。归家之情难以言表,归家之心无以言表。当然生活和工作要照旧,只是多了归家的期盼。

2025年元旦登高

佘山每年都有元旦登高的活动,虽然没有抢到名额,但是并不影响我们去佘山登高。元旦当日上午到东佘山,新年在这里登高赏景。长长的台阶上贴满了徐霞客的诗句,啥时候能像霞客那样游历山水。

东佘山虽然不高,在上海的地位可不算低,加上元旦登高活动,来这里的人特别多。也许是因为来玩的人太多,我并无心赏景,看着大大小小的人络绎不绝,也不知那些人是什么心思。一片是欢乐,一片是求索,另一片却写满了忧愁。

元月流感

外甥女流感发烧到39.8,大半夜去医院急诊检查,验血结果显示轻微甲流。医生开抗甲流的药和一些退烧药,吃过药回家。看病期间看到一个小孩发烧到抽搐,她的妈妈哭喊着显得十分着急,医生开了特权,让护士先去拿针剂救人。

老爸在家里也是发烧,病情有点严重。老爸说这次症状比疫情的时候还要厉害。我们之间的物理距离过远,只能期望病情早日好转,身体没有大碍。

而我则是轻微流鼻涕,喝点清热解毒口服液预防一下,撑一撑就过去了。

博客装修

记不清上一次折腾过博客主题是什么时候了。趁着一年一次更改配色的时机把配色切换功能优化一下。为了防止代码过多,精简需求,代码量不大。

回过头来想想,大多数人应该不会主动切换网页配色。作为访客其实不并不关心站点是否拥有切换配色的功能,除非默认配色太辣眼。尝试绿色希望网页看起来更舒服些,但是我仍然保留了之前的配色以供访客选择。

老姐家装修

年前装修接近尾声。瓷砖贴好,师傅也要回老家过年了。趁着放假前把厨房卫生间铝扣板吊好,橱柜上门量了尺寸。剩下的活要等过了年才能干,预计过了十五才能开工。年后要做油漆,瓷砖美缝,橱柜安装,灯具、厨具、卫浴安装。

一天路过的邻居进来参观,我们大致聊了聊装修和家庭。他说我也要想想自己,以后也会有自己的家庭。听到这里我无法反驳,毕竟拥有自己的家庭看上去是顺理成章的事,但做起来却是一座座大山等待翻越。

公司年会

年会在上海西岸美高梅酒店召开,虽然我是来混饭,并期望抱大奖回家的,但是当我看到20年、30年的员工上台领奖时别有感触。

在一家公司服务多少年算多,每5年都是一个坎,尤其是在跳槽机会很多的上海,能坚持二三十年实属不易。想到前同事的一句话,那时我们在公司宿舍。他说,保不准我们会在这里干到退休。

骑车

除了通勤骑车,没有其他骑车活动,我想是自己懒惰了。

总里程292.24km
总时长13:46:28
骑行次数26
月均速21.22km/h

天冷加上春节假期,等过了年再慢慢恢复吧,等天暖和了再想着提升。虽然很想买公路车,但这些天关注了折叠车,感觉折叠车也不错。也许是我的需求在变,然而我的能力有限,才使得我在这两个选择中间不断徘徊。

踏上归途

过年回家要带点什么。逛逛山姆,看看盒马。无论买什么父母都不新奇,他们只盼着我们早日回家。

今年跟老姐一起回家,带两个小孩,我们一行5人刚好一辆车,可以换着开。回河南老家1000多公里,为避开拥堵我们多跑了100多公里,从四点多天不亮出发到天黑还在路上,到家已经是晚上十点多。

越往北越冷,冬天的感觉越来越明显。到河南郑州时遇到雨夹雪伴有雾气,再往西雨水渐消雪花打在前挡风上,小外甥女唱起了雪花,小外甥也跟着唱了起来。

千万雪花,竞相开放

雪花, 雪花,开在阳光下

休整重来

一年结束一年开始,迷茫之际需要休整。虽然仍会不知方向陷入迷惘,但这一刻停留在过去,生命仍在继续。

该休息时休息,该思考时思考,该努力时努力。

一年一配色:深海绿,升级工具栏切换主题配色

自2023年开始,一年一配色,不知不觉已经是第三个年头。今年的配色为深海绿,该颜色取自中国色1,绿色养眼也静怡。希望生活是平静安逸的,未来只需要慢慢变好,慢慢变得完美,慢慢变得符合预期。

往年配色

深海绿配色

深海绿
#1a3b32
网站背景

云杉绿
#15231b
卡片背景

嫩菊绿
#f0f5e5
字体颜色

艾背绿
#dfecd5
标题颜色

蓝绿
#12a182
链接颜色

飞泉绿
#497568
边框颜色

莽丛绿
#141e1b
其他

  1. 中国色 https://www.zhongguose.com ↩︎

首页截图

主题工具栏

2024年先做了文章目录,后又做了返回顶部,随后将这些工具按钮归为工具栏,这样可以统一管理,以后更改配色会很方便。

2025年对工具栏进行升级优化,主要更改了切换配色功能,不仅仅可以浅色、暗色之间切换,还可以切换到其他配色。

修整自行车,升级后拨导轮。自己动手的乐趣在于及时解决问题

自从开通了两个公众号,博客已经很久没更新了。和预想的差不多,公众号的数据流量不会太好,但有希望。首要目标是500粉丝,现在还差很远。

按照现在的能力和精力只能主做其中一个博客研究社,另一个公众号还在等待时机,当有多余的精力时再打造FENG.PUB

不过当务之急还是修整自行车,自从发现自行车问题将近一个月了。虽然还能骑,但是骑着不舒心。

自行车修整升级

通过这次修整,对自行车一些问题又有了新的认识。

之前以为后拨变速器坏了需要更换,没想到是后拨调节螺丝滑了,达不到调节效果,只需要更换这个螺丝就行。

还有,尾钩变形,导致后拨导轮与飞轮不成一条线。我以为需要更换尾钩,没成想只要把尾钩撬一撬就可以调整了。

除了修整还有升级,这次对后拨导轮进行升级,更换为带有轴承的导轮。

虽然通过网络得知更换后拨大鸡腿可以更省力,但我还是保守一点,保持11齿导轮大小不变,更换带轴承的导轮。淘宝这样的导轮一个只需要8块钱,果断买了2个。不知道换过导轮能省多少力气,速度会不会有所提升。

没有什么经验,所以我预留了充足的时间用于修整和升级自行车。过程是反反复复,感觉不对拆了重装。更换导轮、后拨拆装、尾钩拆装、调整尾钩、调节变速、拆装后刹车片,用时近4小时。

为什么要自己动手

两个直接原因,致使自己动手修整升级自行车。

了解自行车结构,快速解决一些小问题。

2千出头的自行车,买的时候就看到评论区有人这样评价:“除了车架,其他的都换掉了”、“刹车异响”、“脚蹬异响”。不过也看到店家积极回复,可以帮着解决这些问题。

买回来先是解决了刹车异响的问题,骑着感觉还行,毕竟比共享单车要好太多了。旅行车兼顾了公路和越野,骑了一段时间才知道这种车是为了装货,什么前车架后尾架,驮个前包后包十分方便。

自从有了这个车,开始关注前拨后拨、刹车、飞轮、车架、轮胎,也是买车之后才对自行车有了新的认识。

在bilibili搜索教程,尝试调整变速器。后又因为看到一句话,“链条清洗十分干净的自行车,绝对大佬”,便清洗了牙盘和飞轮,也清洗了链条,但是链条始终油乎乎的。

之后自行车有什么小问题,自己能很快解决。随后在车座下方加装了小包,放了常用的内六角、补胎片和打气筒,以备不时之需。

省工时费,买配件和工具。

当我把自行车骑到车店,表示断了一根辐条时,店家看过自行车辐条,表示没有这么长的。又找了一家店,店家正在忙需要等待,那时天色渐晚,决定先回家再说。

大致了解更换辐条的步骤,虽然简单,但是工时可能会比较多。轮子拆下来,内胎、外胎都要拆下来,装好辐条还要调整偏摆,装好内外胎,再把轮子装好。

这一套流程下来要花费不少工时,更何况我这车子的辐条材质是钢的,比不上碳纤维的价格,计时更换整个轮子的辐条也花不了多少钱。

剩下的工时费,可以买配件和工具,而我又喜欢自己动手,所以开始在网上买工具买配件。

❌