使用 SvelteKit 使用外部 API 有效,但仅在重新加载路由之后

Consuming external API using SvelteKit works but only after reloading route

使用 SvelteKit 1.0.0-next.95 从外部 API 端点获取 JSON 数组并显示在如下模板中:

<script context="module">
  export async function load({ fetch }) {
    const url = 'https://www.schoolhouseyoga.com/api/announcement'
    const res = await fetch(url, {
      method: 'GET',
      mode: 'cors',
      headers: {
        'content-type': 'application/json'
      }
    })

    if (res.ok) {
      return {
        props: {
          sections: await res.json()
        }
      }
    }

    return {
      status: res.status,
      error: new Error(`Could not load ${url}`)
     }
  }
</script>

<script>
  export let sections = []
</script>

<template>
  <section>
    {#if sections.length > 0}
      <div class="callout">
        <h1>Announcements</h1>
        {#each sections as section}
          <div>
            {#if section.announcements.length > 0}
              <h2>{section.section}</h2>
            {/if}
            {#each section.announcements as announcement}
              <p><b>{announcement.title} </b>- {@html announcement.description}</p>
            {/each}
          </div>
        {/each}
      </div>
    {/if}
  </section>
</template>

如果您在浏览器中尝试 https://www.schoolhouseyoga.com/api/announcement (CORS) 或使用 curl,您将得到一个包含两个元素的 JSON 数组。

当我 运行 在开发模式下 npm run dev -- --open 并在 Safari 14.1 (macOS) 上导航到此路由时,我收到 500 错误和消息“Origin http://localhost :3000 不被 Access-Control-Allow-Origin 所允许。”如果我尝试导航到 Google Chrome 上的那条路线,我会收到 500 错误和“TypeError:无法获取”。

但是无论使用哪种浏览器,如果我刷新页面,数据都会成功加载。导航到另一条路线然后再次返回,错误再次出现。

我猜这与 SSR 有关,但不确定该怎么做。

有什么想法吗?

该问题与服务器端呈现和端点的 CORS 问题有关。当服务器端代码执行提取时,它工作正常。客户端正在执行后续提取(运行 进入 CORS 问题)。

虽然端点似乎启用了 CORS...

import { Router } from 'express';
import cors from 'cors';
import * as controller from './announcement.controller';

const router = Router();

router.get('/', cors(), controller.index);

但端点也在使用头盔并且需要

app.use(helmet.permittedCrossDomainPolicies());

在加载路线之前。

希望这对其他人有帮助。