Sapper/Svelte: 如何获取本地 json 文件以检索数据

Sapper/Svelte: how to fetch a local json file to retrieve data

在我的 sapper 应用程序中,我将一些数据存储在 json 文件中 src/data/videoslist。json,json 格式的对象数组。

我需要检索索引页中的数据以将其传递给组件。这是我在 src/routes/index.svelte

顶部的代码
<script context="module">
    export async function preload() {
        const response = await this.fetch('../data/videoslist.json');
        const responseJson = await response.json();
        return {
            videos: responseJson
        }
    }
</script>

我收到错误 500

invalid json response body at http://127.0.0.1:3000/data/videoslist.json reason: Unexpected token < in JSON at position 0

文件是纯粹的 json,没有别的。意外标记 < 让我觉得返回的是 404 而不是文件。

你知道我错了吗?我尝试了很多路径变化机智 ../ ./ 或将文件移动到路由文件夹,但没有任何效果。

PS:我仍然是 js 和框架方面的新手,对于更了解的人来说,我可能错过了一些非常基本的东西:)(就像你不能用 fetch 检索本地文件一样) .

在 Sapper 中,当您尝试获取 json 文件时,它实际上会查找名称为 videoslist.json.js 的 route/file,您必须创建该文件,并将其 return json。您可以在此处的文档中找到相关示例:https://sapper.svelte.dev/docs#Server_routes

将JSON文件写入static文件夹,如static/data/videoslist.json.

Rich 的解决方案非常有效。

我刚刚将 json 文件移动到静态文件夹中,下面的代码现在可以工作了。

<script context="module">
    export async function preload() {
        const response = await this.fetch('videoslist.json');
        const responseJson = await response.json();
        return {
            videos: responseJson
        }
    }
</script>

此解决方案无需处理服务器路由和路径即可直接访问文件。

我注意到以下情况:

<script context="module">
    export async function preload({ params: { id } }) {
       return await (await this.fetch(`/route/${id}/details.json`)).json();
    });
</script>

...SSR 代码将尝试加载 https://127.0.0.1/route/id/details.json - 这在我的主机上失败了。如果我指定一个完全限定的绝对 URL (外部可访问),例如

this.fetch(`https://hostname.tld/route/${id}/details.json`)

..它工作正常。我设置了 details.json.js 服务器路由,当通过 https://hostname.tld/route/id/details.json

直接访问 URL 时,它按预期工作

Sapper 显然在服务器 500 之后在客户端运行相同的代码,因此该页面仍然有效,但有点混乱。

我在预加载脚本中遇到了类似的问题,因为托管服务提供商因缺少引荐来源而阻塞(导致 403),可以通过以下方式缓解:

this.fetch(`/route/${id}/details.json`, { referrerPolicy: "origin" })

...但是,这在这种情况下似乎没有帮助。

我显然可以将 URL 更改为绝对值,但我宁愿不将其绑定到主机,搞砸本地开发人员,并显然强制 SSR 代码离开本地网络。我想我不清楚服务器端如何获取本地主机,所以可能不是特定于 sapper 的问题。

N.B。我可以利用预加载页面参数中的 "host" 构造一个绝对 URL 因此(必须是 http 而不是 https):

<script context="module"> 
   export async function preload({ host, params: { id } }) { 
      return await (await this.fetch(`http://{host}/route/${id}/details.json`)).json(); 
   });
</script>

...它适用于托管 - 但担心它不直观,而且不像文档所建议的那样。