如何在路由之外的 Sapper 项目中使用 fetch?

How to use fetch in a Sapper project outside of routes?

在 Sapper 中,可以在 <script context="module"> 内的 preload() 函数中使用 this.fetch。 Sapper 然后确定是使用 fetch.

的客户端版本还是服务器版本
<script context="module">
    export async function preload() {
        const res = await this.fetch(`something.json`);
    }
</script>

在路由中写入所有请求并不能很好地扩展,因此有必要创建一个 api 服务来执行以下操作:

<script context="module">
    import {getJson} from 'api';

    export async function preload() {
        const res = await getJson();
    }
</script>

这会产生一个问题,因为在 preload() 函数之外没有 Sapper 提供的 this 上下文,因此当 运行 在 Node 上下文中时没有 this.fetch 可用(加载应用程序的第一页并进行 SSR 时)。之后所有请求都是从浏览器发出的,因此常规 fetch 可用。

一个解决方案可能是在 api 服务中使用 Node 的 HTTP 客户端,例如 node-fetch,然后在运行时使用 process.browser 确定我们是否需要使用 fetchnode-fetch.

有没有更好的方法来克服这个 Sapper 限制?

您提出的解决方案是最常见的解决方案。 另一种方法是将 this.fetch 作为参数传递给 getJson 方法:

<script context="module">
    import {getJson} from 'api';

    export async function preload() {
        const res = await getJson(this.fetch);
    }
</script>

this.fetch 仅用于路由(想想 Nuxt 中的 asyncData)。 使用 Axios 也是一种常见的解决方案,因为它允许编写在两种环境中执行相同的代码而无需修补 fetch(就像使用 node-fetch 一样)。