You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 21:19:57