SvelteKit应用程序在页面刷新时发送纯文本文件而不是HTML文件,从而导致文件下载



我正在使用SvelteKit构建一个投资组合项目,并使用无服务器功能将其托管在Vercel上。我正在使用SvelteKit进行所有操作,从路由到无服务器函数实现。我遇到的问题是,当我使用npm run dev在本地测试时,甚至当我使用npm run build在本地构建应用程序并使用npm run preview进行测试时,一切都 100% 正常工作,但是在您将其推送到 Vercel 之后,如果您转到/dashboard并刷新它会将文件作为八位字节流文件而不是 HTML 文件发送, 导致浏览器下载它。

如果您在该站点注册,然后被重定向到/dashboard一切正常,但是一旦您在那里刷新浏览器,它将下载一个文件。我注意到在 .vercel_build_output 文件夹中有一个索引.html文件和一个没有文件扩展名的仪表板文件。

到目前为止我尝试过:

  • 更新了所有 NPM 包
  • 使用适配器网络托管在Netlify上,以查看它是否是Vercel特定的问题,它执行相同的操作,但不是八位字节流文件,它只是发送一个txt文件
  • 禁用了所有页面的预呈现。.vercel_build_output文件夹中不再有纯文本仪表板文件,但在刷新时,它会显示一个显示[Object object]的页面,而不是发送 HTML/八位字节流文件
  • 删除了仪表板 __layout.svelte 中的加载功能,因为它是唯一具有加载功能的页面。它会破坏页面,因为它无法获取用户数据,但它仍然在刷新时发送文件
  • 更改了项目内部的文件系统结构,以尝试使其正确构建

链接:

  • 部署:https://stox-wheat.vercel.app/
  • GitHub: https://github.com/clarence-adams/stox

SvelteKit 是一个非常年轻的工具,所以整个问题可能是一个错误,但我不知道我是否是一个傻瓜或它是一个错误!几天来我一直被这个问题打败了,所以非常感谢任何帮助!

你的钩子.jshandle()方法检查路径是否以"dashboard"开头,并尝试返回 303 重定向响应。但是,响应对象缺少'Redirect'正文。如果添加正文,则不再导致[Object object]

这绝对是预渲染期间发生的事情,但我不确定为什么在注册后会发生这种情况。authToken大概会被定义。也许身份验证/cookie代码中还有另一个错误。(啊,也许预渲染的dashboard文本文件是从静态文件夹加载的。

我的问题最终有两个原因:

由于
  1. 某种原因,由于刷新时的 SameSite 属性,我的 AuthToken cookie 没有发送到服务器端,我认为这可能与我正在使用的无服务器环境有关。

  2. Leftium 是对的,这个问题与我的钩子.js文件有关,这与重定向有关,即使用户在获得授权的情况下不应该点击它们。如果我注释掉句柄函数中的代码并且只有以下代码,它将正常重定向:

export async function handle({ event, resolve }) {
const response = await resolve(event);
return response;
}

解决方案:我在 authToken cookie 上将 SameSite 设置为 none,而不是使用 hooks.js 文件来保护以/dashboard开头的端点,我只是单独保护每个端点。我将对钩子.js文件进行更多测试,看看是否可以找出真正的原因。

更新:Leftium 是 100% 正确的,如果 authToken 未定义,我只是没有在我的句柄函数中的响应对象中包含主体,但如果解析 JWT 时出错,我确实包含一个,这是我检查的,并且没有验证以前的响应对象也有正文。此外,正如 Leftium 所想的那样,我的代码在句柄函数中存在一个错误,导致 authToken 未定义,并导致在部署时发送错误的响应对象,而不是在本地发送。

更新:我的句柄函数中没有导致身份验证令牌cookie无法解析的错误。我查看了构建日志,SvelteKit 正在预渲染/dashboardapi 重定向到/,以便/dashboard始终重定向到/而不运行句柄函数。仅当我的钩子.js文件在句柄函数内部具有条件重定向时,才会发生这种情况。即使我将预呈现设置为 false/src/routes/dashboard/index.svelte为 false,npm run build也会始终从句柄函数预呈现重定向。"解决方案"是在svelte.config.js中禁用整个应用程序的预呈现。以下是构建日志的相关部分:

Prerendering
303 /dashboard -> /
200 /

最终更新:SvelteKit 会抓取您的代码以确定要预呈现的路由。SvelteKit正在预渲染我的重定向,因为当它抓取我的代码时,它会被重定向,因为它没有authToken cookie。我将这段代码添加到钩子内部的句柄函数顶部.js一切都在 dev 和 prod 中按预期工作!

import { prerendering } from '$app/env';
// prevents SvelteKit from prerendering the following redirect during build
if (prerendering) return await resolve(event);

最新更新