英文:
Sveltekit's handleFetch in hooks only properly intercepts fetch call upon full page reload
问题
我正在使用Sveltekit的handleFetch
类型来拦截任何fetch请求以设置Authorization头部。它在完整页面重新加载时正常工作(例如,通过按下F5或导航到使用授权的页面并在url栏中输入它)。但是,它不适用于a href
、redirect
或不刷新整个页面的初始加载。奇怪的是,hooks.server.ts
中的代码被执行,并且头部被正确设置,因为我可以看到console.log
语句。此外,在失败的尝试之后(例如通过a href
或redirect
),需要进行完整页面重新加载,以使任何其他页面再次正确加载。
我做错了什么?
hooks.server.ts
:
import { redirect, type HandleFetch } from "@sveltejs/kit";
export const handleFetch = (async ({ event, request, fetch }) => {
if (request.url.startsWith('http://')) {
request.headers.set('Authorization', `Bearer ${event.cookies.get('access_token')}`)
}
// This logs to the console properly
console.log("Modified fetch request")
console.log(request.headers);
return fetch(request);
}) satisfies HandleFetch;
route
文件夹中的page.ts
:
import type { PageLoad } from './$types';
export const load: PageLoad = async ({ fetch }) => {
const response = await fetch('http://127.0.0.1:8080/api/v1/fetch_accounts', {
method: 'GET',
credentials: 'include'
});
let content = await response.json();
return { content };
};
英文:
I am using Sveltekit's handleFetch
type to intercept any fetch request to set an Authorization header. It works as intended on full page reloads (e.g., by pressing F5 or navigating to the a page that uses authorization via typing it in the url bar).
However, it does not work via a href
, redirect
or on an initial load that does not refresh the entire page. Strangely enough, the code in hooks.server.ts
is executed and the header is set properly as I can see the console.log
statements.
Also, after a failed attempt (i.e. via a href or redirect), a full page reload is necessary for any other page to load properly again.
What am I doing wrong?
hooks.server.ts
import {redirect, type HandleFetch } from "@sveltejs/kit"
export const handleFetch = (async ({ event, request, fetch }) => {
if (request.url.startsWith('http://')) {
request.headers.set('Authorization', `Bearer ${event.cookies.get('access_token')}`)
}
// This logs to the console properly
console.log("Modified fetch request")
console.log(request.headers);
return fetch(request);
}) satisfies HandleFetch;
page.ts
in the route folder:
import type { PageLoad } from './$types';
export const load: PageLoad = async ({ fetch, }) => {
const response = await fetch('http://127.0.0.1:8080/api/v1/fetch_accounts', {
method: 'GET',
credentials: 'include'
});
let content = await response.json();
return { content };
};
答案1
得分: 2
handleFetch
仅在服务器上运行的fetch中运行(来自文档)
此函数允许您修改(或替换)在服务器上运行的load或action函数内发生的fetch请求(或在预渲染期间发生的请求)。
+page.ts
中的load
函数仅在第一次请求时在服务器上运行,但对于后续导航,它在客户端上运行(可以将其视为一旦在浏览器上就像是单页面应用程序)。
一个可能的解决方案是将load
移至+page.server.ts
,这个load函数将始终在服务器上运行。另一个选择是通过+server.js
路由代理您的请求。
英文:
handleFetch
only runs for fetches run on the server
(from the docs)
> This function allows you to modify (or replace) a fetch request that happens inside a load or action function that runs on the server (or during pre-rendering).
the load
function in +page.ts
runs on the server for the first request, but runs on the client for subsequent navigation (think of this as if once you are on the browser you are in a single page application).
A possible solution is to move the load to +page.server.ts
, this load function will always runs on the server instead.
Another option is to proxy your request via a +server.js
route.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论