使用NestJS生成网站的站点地图

站点地图的定义和作用 如果将你的网站比作一个博物馆,那么访问的用户(通常是搜索引擎)可以通过博物馆的地图(站点地图)了解到博物馆的各个场馆(网页)、展示品(网页中的视频、图片)是如何构成的。 更详细专业的解释如下: 站点地图是一种文件,您可在其中提供与您网站中的网页、视频或其他文件有关的信息,也可以说明这些内容之间的关

文章 · NestJS · 2024/12/03

站点地图的定义和作用

如果将你的网站比作一个博物馆,那么访问的用户(通常是搜索引擎)可以通过博物馆的地图(站点地图)了解到博物馆的各个场馆(网页)、展示品(网页中的视频、图片)是如何构成的。

更详细专业的解释如下:

站点地图是一种文件,您可在其中提供与您网站中的网页、视频或其他文件有关的信息,也可以说明这些内容之间的关系。Google 等搜索引擎会读取此文件,以便更高效地抓取您的网站。站点地图会告诉搜索引擎您认为网站中的哪些网页和文件比较重要,还会提供与这些文件有关的重要信息。

——来自Google Search

站点地图的结构

站点地图是一个xml格式的文件,它包含网站的各个URL列表,每个URL列表可以包含以下字段

  • <loc>:页面的完整 URL。
  • <lastmod>:最后修改时间(可选)。
  • <changefreq>:建议爬取频率(可选)。
  • <priority>:页面重要性(可选,0.0 - 1.0)

为自己的网站设计站点地图

如果网站仅仅是静态网站,那么站点地图其实可以直接手写。

那如果网站会进行更新,手写站点地图就变得异常麻烦了,就需要用到后端接口来实现。

以我的网站花墨为例,可以将它分类为三个最重要的模块:首页、技术文章、其他

  1. 其中首页一定是最重要的,是整个网站的入口。
  2. 其次是技术文章,因为文章会随时更新,所以需要连接数据库进行查询遍历去生成对应的站点地图,有10篇就会有10条URL列表。
  3. 其他则是网站不太重要的组成部分,例如生活相关、关于我和网站的介绍等等。

使用NestJS生成站点地图

安装库

npm install sitemap

创建站点地图控制器

import { Controller, Get, Header, Res } from '@nestjs/common';
import { Response } from 'express';
import { BlogService } from './blog.service';

@Controller()
export class SitemapController {
  constructor(private readonly blogService: BlogService) {}

  @Get('sitemap')
  async getSitemap(@Res() res: Response): Promise<void> {
    const sitemap = await this.blogService.generateSitemap();
    res.setHeader('Content-Type', 'application/xml'); // 明确设置内容类型
    res.status(200).send(sitemap); // 直接发送生成的 XML
  }
}

创建站点地图服务

import { SitemapStream, streamToPromise } from 'sitemap';
// 站点地图
  async generateSitemap(): Promise<string> {
    const blogs = await this.findAllBlog({
      type: '文章',
      title: undefined,
      content: undefined,
      tag: undefined,
      date: null,
      star: undefined,
    });

    // 创建站点地图流
    const sitemap = new SitemapStream({
      hostname: 'https://flowersink.com',
    });

    // 静态页面
    const staticPages = [
      { url: '/', changefreq: 'daily', priority: 1.0 },
      { url: '/blog/article', changefreq: 'weekly', priority: 0.8 },
      { url: '/blog/question', changefreq: 'weekly', priority: 0.8 },
      { url: '/blog/all', changefreq: 'weekly', priority: 0.8 },
      { url: '/life/heart', changefreq: 'monthly', priority: 0.7 },
      { url: '/about/me', changefreq: 'monthly', priority: 0.6 },
      { url: '/about/website', changefreq: 'monthly', priority: 0.6 },
      { url: '/about/message', changefreq: 'monthly', priority: 0.6 },
    ];

    // 添加静态页面到站点地图
    staticPages.forEach((page) => sitemap.write(page));

    // 动态博客
    blogs['blogs'].forEach((blog) => {
      sitemap.write({
        url: `/blog/${blog.id}`,
        changefreq: 'weekly',
        priority: blog.star ? 0.9 : 0.7,
        lastmod: blog.date,
      });
    });

    sitemap.end();

    // 将站点地图转换为字符串
    return streamToPromise(sitemap).then((data) => data.toString());
  }

验证

我们直接访问站点地图接口:https://api.flowersink.com/sitemap,就可以成功在页面查看到了。