为什么在 svelte-kit 的 load 函数中,在服务器上运行代码时无法解析有效路由
Why in svelte-kit's load function a valid route can't be resolved when code runs on the server
在我的 svelte-kit 应用程序中,我遇到了这个 NODE 错误 ERR_INVALID_URL but was able to fix it with a solution provided in this 。不幸的是,关于为什么 NODE 无法解析 url 的更深入的解释——当代码在客户端上运行时,这显然只是一个有效的路由——被忽略了。
在 svelte-kit 的 load
函数中,我隐式 fetch
-ing 一个,从 nodejs 的角度来看,无效的 url (ERR_INVALID_URL)
所以我想了解的是,为什么 NODE 无法 resolve/parse 给定的 url?
先决条件:
// in $lib/utils/http.js
export function post(endpoint, data = {}) {
return fetch(endpoint, {
method: "POST",
credentials: "include",
body: JSON.stringify(data),
headers: {
"Content-Type": "application/json",
},
}).then((r) => r.json());
}
// in routes/auth/login.js -> this endpoint can't be be found by NODE
export async function post({ locals, request }) {
// ...code here
return {
body: request.json()
}
}
这里要区分代码是运行在客户端还是服务端:
// in routes/login.svelte
import { browser } from '$app/env';
import { post } from '$lib/utils/http.js';
export async function load() {
const { data } = someDataObject;
if (browser) { // NODE wouldn't be able to find the endpoint in question ('/auth/login'), whereas the client does
return await post(`/auth/login`, { data }).then((response) => {
// ...do something with the response
});
}
return {};
}
感谢任何对此有所启发的解释。
您应该重构 load
函数以使用 SvelteKit 提供的 fetch
。这将允许您在服务器上使用相对请求,这通常需要一个来源。来自 the docs(强调我的):
fetch is equivalent to the native fetch web API, with a few additional
features:
- it can be used to make credentialed requests on the server, as it inherits the cookie and authorization headers for the page request
- it can make relative requests on the server (ordinarily, fetch requires a URL with an origin when used in a server context)
- requests for endpoints go direct to the handler function during server-side rendering, without the overhead of an HTTP call
- during server-side rendering, the response will be captured and inlined into the rendered HTML
- during hydration, the response will be read from the HTML, guaranteeing consistency and preventing an additional network request
因此,从传递给 load 的参数中获取 fetch
...
export async function load({ fetch }) {
const { data } = someDataObject;
return await post(`/auth/login`, fetch, { data }).then((response) => {
// ...do something with the response
});
}
... 并在您的 post
函数中使用它
// in $lib/utils/http.js
export function post(endpoint, fetch, data = {}) { /* rest as before */ }
一个 future enhancement to SvelteKit 可能会成功,因此您不必将 fetch
传递给您的效用函数,但这是您现在必须做的。
在我的 svelte-kit 应用程序中,我遇到了这个 NODE 错误 ERR_INVALID_URL but was able to fix it with a solution provided in this
在 svelte-kit 的 load
函数中,我隐式 fetch
-ing 一个,从 nodejs 的角度来看,无效的 url (ERR_INVALID_URL)
所以我想了解的是,为什么 NODE 无法 resolve/parse 给定的 url?
先决条件:
// in $lib/utils/http.js
export function post(endpoint, data = {}) {
return fetch(endpoint, {
method: "POST",
credentials: "include",
body: JSON.stringify(data),
headers: {
"Content-Type": "application/json",
},
}).then((r) => r.json());
}
// in routes/auth/login.js -> this endpoint can't be be found by NODE
export async function post({ locals, request }) {
// ...code here
return {
body: request.json()
}
}
这里要区分代码是运行在客户端还是服务端:
// in routes/login.svelte
import { browser } from '$app/env';
import { post } from '$lib/utils/http.js';
export async function load() {
const { data } = someDataObject;
if (browser) { // NODE wouldn't be able to find the endpoint in question ('/auth/login'), whereas the client does
return await post(`/auth/login`, { data }).then((response) => {
// ...do something with the response
});
}
return {};
}
感谢任何对此有所启发的解释。
您应该重构 load
函数以使用 SvelteKit 提供的 fetch
。这将允许您在服务器上使用相对请求,这通常需要一个来源。来自 the docs(强调我的):
fetch is equivalent to the native fetch web API, with a few additional features:
- it can be used to make credentialed requests on the server, as it inherits the cookie and authorization headers for the page request
- it can make relative requests on the server (ordinarily, fetch requires a URL with an origin when used in a server context)
- requests for endpoints go direct to the handler function during server-side rendering, without the overhead of an HTTP call
- during server-side rendering, the response will be captured and inlined into the rendered HTML
- during hydration, the response will be read from the HTML, guaranteeing consistency and preventing an additional network request
因此,从传递给 load 的参数中获取 fetch
...
export async function load({ fetch }) {
const { data } = someDataObject;
return await post(`/auth/login`, fetch, { data }).then((response) => {
// ...do something with the response
});
}
... 并在您的 post
函数中使用它
// in $lib/utils/http.js
export function post(endpoint, fetch, data = {}) { /* rest as before */ }
一个 future enhancement to SvelteKit 可能会成功,因此您不必将 fetch
传递给您的效用函数,但这是您现在必须做的。