【问题标题】:SvelteKit server-side rendering: creating XML responsesSvelteKit 服务器端渲染:创建 XML 响应
【发布时间】:2021-11-29 11:34:56
【问题描述】:

如何使用 SvelteKit 呈现 XML 或其他非 HTML 输出?我想使用 SvelteKit 为我的博客呈现 Google sitemap.xml 和 RSS 提要。

【问题讨论】:

    标签: sveltekit


    【解决方案1】:

    您将创建一个端点并定义一个不同的Content-Type

    // example.xml.js
    export async function get() {
      const xml = 
    `<?xml version="1.0" encoding="UTF-8"?>
    <data>
      <field>This is an example</field>
    </data>
    `
      return {
        status: 200,
        body: xml,
        headers: {
          'Content-Type': 'application/xml'
        }
      }
    }
    

    替代方法

    如果您愿意,您可以创建一个常规路线,您可以在其中使用 Svelte 组件并在 handle 挂钩中劫持渲染,但这种方法非常脆弱,因为仅更改标题是不够的,文件仍将被渲染其他通常与它周围的 html 页面相关的绒毛(例如 body 和 head 标签),所以你必须先找到一种方法来删除它们。

    <!-- example.xml.svelte -->
    <script>
      let value = 0
    </script>
    <data>
      <field>{value}</field>
    </data>
    
    // hooks.js
    export async function handle({ request, resolve }) {
        const response = await resolve(request)
    
        if (request.path.endsWith('.xml')) {        
            // Set the content type to xml
            response.headers["content-type"] = "application/xml"
    
            // remove whitespace
            response.body = response.body.replaceAll('\n','')
            response.body = response.body.replaceAll('\t','')
    
            // find the body tags if present
            const start = response.body.indexOf('<body>')
            const stop = response.body.indexOf('</body>')
            if (start > 0 && stop > 0) {
                // only show the content of the body
                response.body = response.body.substring(start + 6, stop)
            }
        }
        return { 
            ...response
        }
    }
    

    【讨论】:

    • 完美。我假设 Svelte 组件本身不能产生 XML 输出,我需要引入另一个模板引擎,比如 Handlebars?
    • 我添加了一个使用常规路由组件的替代方案,但在我看来相当“hacky”。​​
    • 是的,我同意 - 最好以干净的方式进行。
    【解决方案2】:

    作为参考,我提供了一个基于 Stephane Vanraes 答案生成 sitemap.xml 的完整示例。

    这里是routes/sitemap.xml.ts

    // sitemap.xml generation
    
    
    // This sitemap is manually maintained and page paths included here one by one
    const staticPages = [
        "",
        "about",
        "trading-view",
        "trading-view/backtesting",
        "community",
        "trading-view/exchanges",
        "trading-view/blockchains",
    ]
    
    
    /***
     * Sitemap.xml HTTP GET endpoint
     *
     * For more information see https://stackoverflow.com/a/69523302/315168
     */
    export async function get(page) {
      
      // SvelteKit page object does not include protocol, so assume HTTPS
      const proto = "https";
    
      // Generate the sitemap.xml file with string fiddling
      const fragments = [];
      for(let path of staticPages) {
        const fullUrl = `${proto}://${page.host}/${path}`;
        fragments.push(`<url><loc>${fullUrl}</loc></url>`);
      }
    
      // Build the XML for pages
      const urlXml = "".concat(...fragments);
    
      // See https://en.wikipedia.org/wiki/Sitemaps
      const xml =
        `<?xml version="1.0" encoding="utf-8"?>
    <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">
       ${urlXml}
    </urlset>`
    
      return {
        status: 200,
        body: xml,
        headers: {
          'Content-Type': 'application/xml'
        }
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2017-01-14
      • 2021-11-30
      • 2021-07-02
      • 1970-01-01
      • 1970-01-01
      • 2021-07-11
      • 2015-05-09
      • 2023-04-09
      相关资源
      最近更新 更多