如何用Next.js代理GCS存储桶并捕获NoSuchKey错误跳转404?
解决Next.js代理GCS时捕获NoSuchKey错误并跳转404的问题
当前通过Next.js代理访问Google Cloud Storage(GCS)资源时,若文件密钥输入错误,GCS返回的错误信息会暴露存储桶名称,示例错误如下:
<Error> <Code>NoSuchKey</Code> <Message>The specified key does not exist.</Message> <Details>No such object: my_secret_bucket/asset.svg</Details> </Error>原Next.js 14代理配置使用
rewrites直接转发请求,无法拦截GCS的错误响应:/** @type {import('next').NextConfig} */ const nextConfig = { async rewrites() { return [ { source: '/assets/photos/:path*', destination: 'https://storage.googleapis.com/my_secret_bucket/:path*' } ] }, async redirects() { return [ { source: '/assets/photos', destination: '/404', permanent: false } ] } } module.exports = nextConfig
解决方案:使用API路由代理请求并拦截错误
直接使用rewrites无法处理GCS的响应内容,因此需要创建自定义API路由来代理请求,从而捕获错误并返回404页面。
步骤1:移除原rewrite配置
修改next.config.js,删除rewrites部分,保留redirects配置:
/** @type {import('next').NextConfig} */ const nextConfig = { async redirects() { return [ { source: '/assets/photos', destination: '/404', permanent: false } ] } } module.exports = nextConfig
步骤2:创建API路由
在app/assets/photos/[...path]/route.ts(App Router)中创建代理路由,代码示例如下:
import { NextResponse } from 'next/server' import { parseStringPromise } from 'xml2js' export async function GET(request: Request, { params }: { params: { path: string[] } }) { const filePath = params.path.join('/') const gcsUrl = `https://storage.googleapis.com/my_secret_bucket/${filePath}` try { const gcsResponse = await fetch(gcsUrl) if (gcsResponse.ok) { // 转发GCS的响应给客户端 return new NextResponse(gcsResponse.body, { status: gcsResponse.status, headers: gcsResponse.headers, }) } else { // 解析GCS的XML错误响应 const errorXml = await gcsResponse.text() const errorData = await parseStringPromise(errorXml) // 判断是否为NoSuchKey错误 if (errorData.Error.Code[0] === 'NoSuchKey') { // 重定向到404页面 return NextResponse.redirect(new URL('/404', request.url), { status: 302 }) } else { // 其他错误返回原状态码和信息(可根据需求自定义) return new NextResponse('Resource unavailable', { status: gcsResponse.status }) } } } catch (error) { // 网络异常等情况直接返回404 return NextResponse.redirect(new URL('/404', request.url), { status: 302 }) } }
步骤3:安装依赖
由于需要解析GCS返回的XML错误信息,需安装xml2js及其类型声明:
npm install xml2js @types/xml2js
说明
- 通过API路由代理请求,可完全控制请求与响应流程,拦截GCS的错误响应并判断错误类型
- 捕获到
NoSuchKey错误时直接重定向到404页面,避免存储桶名称暴露 - 其他错误可根据业务需求自定义处理逻辑,比如统一返回404或自定义错误提示
内容的提问来源于stack exchange,提问作者Luka Fridonich Donadze
相关产品推荐
相关产品推荐

