使用Cloudflare Workers创建动态生成的Sitemap
我的网站使用前后端分离,前端是Vue,后端是Asp.NET core。我正在给我的网站做SEO优化。由于搜索引擎对单页应用支持不好,而我的网站前端又是托管在Cloudflare Pages上,因此很难执行服务端渲染优化。因此我决定使用sitemap来加快搜索引擎收录的速度。
如果你已经使用CMS,请不要使用这种方法生成sitemap。
首先登录Google Search Console,验证网站所有权。验证方式可以选择网域和网址前缀验证。我选择了网址前缀验证。我使用的方法是HTML文件验证。通过上传谷歌提供的文件到网站根目录,完成所有权验证。通过验证后不能移除验证文件,否则所有权验证会过期。
在 控制台>编制索引>站点地图 中可以添加站点地图。
生成sitemap.txt
查询谷歌的文档,发现谷歌支持多种格式的sitemap。我决定首先从简单格式的sitemap开始。
谷歌提供的示例如下
https://www.example.com/file1.html
https://www.example.com/file2.html
为了在Cloudflare Workers中生成这样的文本,我需要从我的API站点中获取已经存在的帖子的数据。我的API站点并不提供帖子的URL信息,因此需要在Worker中执行转换。
转换代码如下:
const mysite = "https://api.example.com/search"
const myblog = "https://example.com/#/blog?id="
async txt() {
const url = `${mysite}`
var data = fetch(url)
.then((response) => response.json())
.then((arr) => {
let sitemap = "";
for (const obj of arr) {
sitemap += `${myblog}${obj.id}\n`;
}
return sitemap;
});
return data;
},
添加Workers路由
在网站>域名>workers路由 中添加以下项目,以便让worker处理谷歌的爬虫。
/robots.txt
/sitemap*
处理多个任务
我决定将多个任务放入单个worker中,这个worker现在可以生成txt和xml格式的sitemap。
worker.js 代码如下
const bing = ``
const google = ""
export default {
async fetch(request, env, ctx) {
const url = new URL(request.url);
const paths = url.pathname.split('/');
if (paths.length > 1) {
switch (paths[1]) {
case 'BingSiteAuth.xml':
return new Response(bing, { headers: { "Content-Type": "text/html" } });
case 'sitemap.txt':
return generateSitemap.txt()
.then((map) => { return new Response(map, { headers: { "Content-Type": "text/plain" } }) });
case 'sitemap.xml':
return generateSitemap.xml()
.then((map) => { return new Response(map, { headers: { "Content-Type": "text/xml" } }) });
case 'robots.txt':
const robots = `User-agent: *
Allow: /
Sitemap: https://${url.hostname}/sitemap.xml\n`
return new Response(robots, { headers: { "Content-Type": "text/plain" } });
}
if (paths[1] == google) {
return new Response(`google-site-verification: ${google}`, { headers: { "Content-Type": "text/html" } });
}
}
return new Response('404 not found', { headers: { "Content-Type": "text/html" }, status: 404 });
},
};
验证
直接用浏览器打开 网站根目录/sitemap.txt 可以看到Worker生成的文本
提交到google search console网站地图,显示发现的网页为n,通过验证。(但这不意味着Google一定会抓取你的网页)
生成XML格式的sitemap
我打算通过直接拼接字符串生成XML,而不使用外部库。
代码如下
async xml() {
const url = `${mysite}`
var data = fetch(url)
.then((response) => response.json())
.then((arr) => {
let sitemap =
`<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
`;
for (const obj of arr) {
sitemap +=
`<url>
<loc>${myblog}${obj.id}</loc>
<lastmod>${obj.createTime}</lastmod>
</url>\n`;
}
sitemap += `</urlset>`
return sitemap;
});
return data;
}
如果接口查询结果已经分页,则需要进行多次查询。
结论
通过Cloudflare Workers实现了动态生成sitemap。好处在于不需要修改源码,更新及时性强。弊端也比较明显,每次请求都要消耗workers请求次数,并且查询会增加后端服务器的负担。