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>
...它适用于托管 - 但担心它不直观,而且不像文档所建议的那样。
在我的 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
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>
...它适用于托管 - 但担心它不直观,而且不像文档所建议的那样。