diff options
-rw-r--r-- | Gemfile | 1 | ||||
-rw-r--r-- | _config.yml | 1 | ||||
-rw-r--r-- | _includes/word_count.html | 1 | ||||
-rw-r--r-- | _layouts/default.html | 2 | ||||
-rw-r--r-- | _posts/2025-04-08-feed.md | 30 | ||||
-rw-r--r-- | js/rss-feed-preview.js | 17 | ||||
-rw-r--r-- | links.md | 3 |
7 files changed, 51 insertions, 4 deletions
diff --git a/Gemfile b/Gemfile index a7adda3..6374f49 100644 --- a/Gemfile +++ b/Gemfile @@ -6,6 +6,7 @@ group :jekyll_plugins do gem "jekyll-assets", "~> 1.0.0" gem "jekyll-sitemap", "~> 1.4.0" gem "jekyll-feed", "~> 0.15.1" + gem "jekyll-include-cache", "~> 0.2.1" gem "jekyll-theme-minimal" gem "jekyll-paginate", "~> 1.1.0" gem "kramdown-parser-gfm", "~> 1.1.0" diff --git a/_config.yml b/_config.yml index 4f78f33..7cab47c 100644 --- a/_config.yml +++ b/_config.yml @@ -10,6 +10,7 @@ paginate: 7 plugins: - jekyll-sitemap - jekyll-feed + - jekyll-include-cache feed: path: atom.xml google_analytics: UA-137710294-1 diff --git a/_includes/word_count.html b/_includes/word_count.html new file mode 100644 index 0000000..8cc1cf1 --- /dev/null +++ b/_includes/word_count.html @@ -0,0 +1 @@ +{% assign count = 0 %}{% for post in site.posts %}{% assign single_count = post.content | strip_html | strip_newlines | remove: " " | size %}{% assign count = count | plus: single_count %}{% endfor %}{{ count }} \ No newline at end of file diff --git a/_layouts/default.html b/_layouts/default.html index 702e531..e2c3128 100644 --- a/_layouts/default.html +++ b/_layouts/default.html @@ -131,7 +131,7 @@ <!-- <![endif]--> <footer> <p> - <small>Made with ❤ by Mayx<br />Last updated at <script>document.write(lastUpdated.toLocaleString());</script><br /> 总字数:{% assign count = 0 %}{% for post in site.posts %}{% assign single_count = post.content | strip_html | strip_newlines | remove: " " | size %}{% assign count = count | plus: single_count %}{% endfor %}{{ count }} - 文章数:{{ site.posts.size }} - <a href="{{ site.feed.path | relative_url }}" >Atom</a> - <a href="{{ "/README.html" | relative_url }}" >About</a></small> + <small>Made with ❤ by Mayx<br />Last updated at <script>document.write(lastUpdated.toLocaleString());</script><br /> 总字数:{{ include_cached word_count.html }} - 文章数:{{ site.posts.size }} - <a href="{{ site.feed.path | relative_url }}" >Atom</a> - <a href="{{ "/README.html" | relative_url }}" >About</a></small> </p> </footer> </div> diff --git a/_posts/2025-04-08-feed.md b/_posts/2025-04-08-feed.md new file mode 100644 index 0000000..e8a9a46 --- /dev/null +++ b/_posts/2025-04-08-feed.md @@ -0,0 +1,30 @@ +--- +layout: post +title: 如何使用JS通过订阅源查看文章? +tags: [JavaScript, RSS, Feed, AI] +--- + + 懒得写代码?那就让AI写!<!--more--> + +# 起因 + 前段时间,我看到有些博客给自己的友链页面做了通过订阅源查看友链最近更新文章的功能,看起来挺有意思的,有点想整一个。不过对于我的博客来说,作为静态博客想要做到这样的功能估计没那么简单吧……毕竟一般的订阅软件需要隔段时间请求一下对应博客的订阅链接,然后再把结果存到数据库才行。但是我想了想,对我来说没必要做成订阅啊,我又不需要知道对应博客是什么时候更新的,只要在有人想知道的时候去请求一下订阅链接,然后展示出来就行,感觉似乎又没有那么复杂。 + 既然不复杂,那这个功能就让AI来做吧,正好前段时间有个朋友买了一个月的Devin.ai订阅,据说是可以自己调试代码,还能操作浏览器,而且代码基本上写出来就能用。我对这个挺感兴趣的,所以这次的功能就让它来写吧! + +# 让AI编写代码 + 既然是让AI来写,至少得把我的需求说清楚,所以首先我应该告诉它: +> 创建一个JavaScript函数来实现[Links](/links.html)表格中链接的RSS/Atom源预览。 +> - 当鼠标悬停在表中的链接上时,检查该网站是否有RSS/Atom源,并将结果显示在一个浮动窗口中 +> - 在鼠标光标后的浮动窗口中显示提要中的5篇最新文章 +> - 在窗口中只包含标题和时间,不需要链接和内容 +> - 跳过所有不包含RSS/Atom源的链接,而不显示任何错误 +> - 当鼠标离开链接时,浮动预览应该消失 + + 不过在正式编写之前,我还得考虑一下可行性,毕竟是很简单的功能,我不写但我不能不知道怎么写。首先让JS解析Feed数据也就是XML数据应该是很简单的事情,JS应该有自带的函数来实现这种功能。然后是获取数据,在JS中使用fetch就可以了,但是这里有个很重要的事情,浏览器请求其他网站存在跨域的问题,还好我之前在CF Workers上用[cloudflare-cors-anywhere](https://github.com/Zibri/cloudflare-cors-anywhere)搭了个CORS代理: <https://cors-anywhere.mayx.eu.org/> 。所以我应该在说明中给它说清楚: +> - 如果存在源,请使用CORS代理:https://cors-anywhere.mayx.eu.org/ 获取并解析它 + + 随后我就开始让它编写代码了。接下来就能看到AI在浏览器和编辑器中切换,不停的进行编写和调试,等了一段时间,它把第一版代码写好了。不过也许我说的不够清楚,这个CORS代理的用法和其他的CORS代理不太一样,代理链接和被代理的链接之间需要使用“?”分开,另外第一版我也没说清楚RSS/Atom源的链接在哪,所以它选择遍历常见的几种订阅源的路径,这样有点不太好,除了速度慢,对我的CORS代理消耗也比较大。所以我告诉它代理的正确用法,以及让它假设超链接中包含“data-feed”属性,其中包含订阅源的链接,并且随便挑了个网站拿给它作为示例。 + 随后就能看到它继续改改改,改了几次之后我把最后生成的JS复制到浏览器上执行了一下,效果还不错,于是就把它放到我的博客上了。 + 它的水平还是挺不错的,至少正确的实现了功能。不过我有点担心它的代码会不会不太可靠,毕竟要从其他网站上获取数据,得避免出现XSS之类的问题,于是我把代码丢给DeepSeek-R1让它检查了一下,果不其然Devin.ai写的代码似乎有XSS的隐患,如果链接列表中标题有html标签似乎就会解析(虽然我没试过),于是根据DeepSeek的提示修改了一下,增加了一个过滤特殊字符的函数,改完又放到博客上,最终的代码就是:[rss-feed-preview.js](/js/rss-feed-preview.js)。 + +# 感想 + 让AI全自动写代码感觉还挺方便,有种当产品经理的感觉了🤣,像这种AI就是Agent吧,这也算是我头一次使用Agent了,感觉用起来还挺不错的。不过从这次尝试来看确实AI也有一定的局限性,像是直接写出来的代码可能存在一些安全性问题,除非单独让AI检查,不然很有可能会写出功能正常但是存在漏洞的代码,所以还是得人看着点,AI搞出事故可是**不负责**的啊😇~ \ No newline at end of file diff --git a/js/rss-feed-preview.js b/js/rss-feed-preview.js index 8d74709..2929622 100644 --- a/js/rss-feed-preview.js +++ b/js/rss-feed-preview.js @@ -90,6 +90,17 @@ return null; }; + const escapeHTML = (str) => { + return String(str).replace(/[&<>"'/]/g, (c) => ({ + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''', + '/': '/' + }[c])); + }; + const renderFeedItems = (previewEl, items, siteName) => { if (!items || items.length === 0) { previewEl.innerHTML = '<p>No feed items found.</p>'; @@ -99,13 +110,15 @@ let html = `<h3>Latest from ${siteName}</h3><ul style="list-style: none; padding: 0; margin: 0;">`; items.forEach(item => { + const safeTitle = escapeHTML(item.title); + const safeDate = escapeHTML(new Date(item.date).toLocaleDateString()); html += ` <li style="margin-bottom: 10px; padding-bottom: 10px; border-bottom: 1px solid #eee;"> <div style="color: #24292e; font-weight: bold;"> - ${item.title} + ${safeTitle} </div> <div style="color: #586069; font-size: 12px; margin: 3px 0;"> - ${new Date(item.date).toLocaleDateString()} + ${safeDate} </div> </li> `; diff --git a/links.md b/links.md index d1ef834..53c4e4a 100644 --- a/links.md +++ b/links.md @@ -8,7 +8,7 @@ tags: [links] | Link | Description | | - | - | -{% for item in site.data.links %}| <a href="{{ item.link }}" target="_blank" data-feed="{{ item.feed_url }}">{{ item.title }}</a> | {{ item.description }} | +{% for item in site.data.links %}| <a href="{{ item.link }}" target="_blank" rel="noopener" data-feed="{{ item.feed_url }}">{{ item.title }}</a> | {{ item.description }} | {% endfor %} ## Links申请 @@ -23,6 +23,7 @@ tags: [links] 名称:Mayx的博客 简介:Mayx's Home Page 链接:<https://mabbs.github.io> +订阅:<https://mabbs.github.io/atom.xml> 头像:<https://avatars0.githubusercontent.com/u/17966333> Logo:<https://mabbs.github.io/favicon.ico> |