Astro searchParams 为 null
预渲染endpoint没有当前访客的query。配置对应adapter和路由prerender=false,核对真实部署、query校验与缓存键。
浏览器请求 /api/search?q=test,Astro endpoint 中 url.searchParams.get('q') 却总是 null,URL 也没有请求里的查询串。先确认这个 endpoint 是否在构建时预渲染:构建过程没有访客稍后发送的查询参数,生成的静态结果无法按每次请求变化。
Astro 4 的 hybrid 项目也可能需要为具体路由关闭预渲染。当前 Astro 5 及之后不再使用 hybrid 输出模式,新配置按 static 或 server 的规则处理,不能照抄旧版 output: 'hybrid'。
让需要请求参数的路由按需运行
当前 Astro 的默认 static 输出可以配合适用于部署环境的 adapter,仅让某些 endpoint 按请求执行。前提是部署目标实际运行 adapter 输出的服务,不能只上传静态目录。
在需要处理查询参数的路由文件中显式设置 prerender = false。下面是 src/pages/api/search.ts 的路由结构示例:
import type { APIRoute } from 'astro';
export const prerender = false;
export const GET: APIRoute = ({ url }) => {
const q = url.searchParams.get('q');
if (q === null || q.trim() === '') {
return new Response('缺少查询参数 q', { status: 400 });
}
return new Response(JSON.stringify({ q }), {
headers: {
'Content-Type': 'application/json; charset=utf-8',
'Cache-Control': 'no-store',
},
});
};
这只展示读取与校验入口,没有执行真实搜索。接入数据库或其他服务前,还应按业务限制输入长度、查询权限、负载与返回内容。不要用未校验的 q 拼接 SQL。
prerender 必须放在实际路由模块里。写在另一个工具文件中,或只修改页面布局,不会自动改变这个 endpoint 的渲染方式。adapter 的安装与配置按其版本及运行环境核对;Node、Cloudflare 等目标不能随意混用部署产物。
不必为了一个 endpoint 把全站改成 server
output: 'server' 会改变路由的默认行为,让它们默认按需渲染。它不是读取 query 的唯一办法。多数页面适合静态输出时,可以保留 static,仅对确实依赖当前请求的路由关闭预渲染。
反过来,在 server 输出中显式设置了 prerender = true 的路由仍是静态路由。检查该文件最终配置,而不是只凭全局 output 判断。
如果只是让浏览器界面根据地址参数筛选已经加载的数据,可在真正运行于客户端的代码中读取 window.location.search。Astro 的服务端 frontmatter 不会因为写了浏览器逻辑就自动变成客户端脚本,静态搜索结果也不会自动变成实时后端查询。
在实际部署上用两个 query 检查
分别请求同一路径的 ?q=alpha 和 ?q=beta,确认 endpoint 收到各自的值,再检查没有 q 时的业务响应。不要只用 dev 模式通过就结束,构建后的路由和托管配置也需要验证。
若按需路由已生效但仍收到相同结果,继续检查反向代理是否保留查询串,以及 CDN 缓存键是否区分 query。示例使用 no-store,实际产品若需要缓存,应按输出内容设计缓存键和权限隔离,不能让不同查询或不同用户共用错误结果。
保存路由、adapter、构建与部署设置后再改动。回退时一起恢复对应服务与产物;仅移除 prerender = false,可能让一个已经依赖请求数据的 endpoint 再次变成静态结果。


