SvelteKit预览正常但node build报错:URL构造函数无效
问题:Debian Apache2部署Svelte应用,node build启动后API请求URL无效报错
现象
在Debian系统的Apache2上部署内部Svelte应用,项目构建成功,但启动方式不同结果异常:
- 执行
npm run preview时应用运行完全正常,可正常获取API数据 - 使用
node build启动后,浏览器控制台抛出错误:Uncaught (in promise) TypeError: URL constructor: 127.0.0.1:4000/api/dashboardtbl is not a valid URL
曾怀疑是build target设为es2018导致问题,尝试改为es2020/esnext后触发构建错误。
相关代码
API请求逻辑
function requestData() { data = []; if (!host) return; const url = new URL(host + '/api/dashboardtbl'); url.searchParams.set('page', page.toString()); url.searchParams.set('pageSize', pageSize.toString()); if (search) { url.searchParams.set('search', search); } if (Object.keys(filters).length > 0) { url.searchParams.set('colFilters', JSON.stringify(filters)); } const dest = url.toString().replace(host, ''); console.log('dest', dest); console.log('host', host); fetch(dest) .then((res) => res.json()) .then((res) => { data = res.rows; maxPages = Math.ceil(res.count / pageSize); options.update((o) => ({ ...o, data })); }); } onMount(async () => { host = window.location.host; requestData(); });
Svelte配置文件
import adapter from '@sveltejs/adapter-node'; import { vitePreprocess } from '@sveltejs/kit/vite'; /** @type {import('@sveltejs/kit').Config} */ const config = { preprocess: vitePreprocess(), kit: { adapter: adapter() } }; export default config;
解决方法
核心问题是URL构造函数的参数不符合要求:window.location.host仅返回主机名:端口格式(如127.0.0.1:4000),缺少协议头(http://或https://),而URL构造函数要求传入完整的有效URL。
为什么npm run preview正常?
npm run preview的服务环境会自动处理相对路径的解析,或者内部对URL做了兼容处理,而node build启动的生产环境下,URL构造函数的严格校验触发了报错。
具体修复方案
修正host获取方式:使用
window.location.origin替代host,它会包含完整的协议+主机+端口(如http://127.0.0.1:4000),满足URL构造函数的要求:onMount(async () => { host = window.location.origin; requestData(); });简化请求逻辑(更推荐):既然最终请求的是相对路径,完全可以跳过
URL构造函数,直接用URLSearchParams拼接参数:function requestData() { data = []; const params = new URLSearchParams(); params.set('page', page.toString()); params.set('pageSize', pageSize.toString()); if (search) params.set('search', search); if (Object.keys(filters).length > 0) params.set('colFilters', JSON.stringify(filters)); fetch(`/api/dashboardtbl?${params.toString()}`) .then((res) => res.json()) .then((res) => { data = res.rows; maxPages = Math.ceil(res.count / pageSize); options.update((o) => ({ ...o, data })); }); } onMount(async () => { // 此方案无需host变量,直接请求相对路径即可 requestData(); });正确配置build target:若需调整编译目标,需在Svelte配置的vite节点下设置,避免直接修改导致构建错误:
kit: { adapter: adapter(), vite: { build: { target: 'es2018' // 填写你的运行环境支持的版本 } } }
内容的提问来源于stack exchange,提问作者Waul
相关产品推荐
相关产品推荐

