Next.js支付API本地正常,部署到Vercel生产环境出现405错误
在Vercel(免费/付费试用版)和GitHub Pages部署使用Square支付API的电商网站时,出现405 Method Not Allowed错误,本地npm run dev运行完全正常。错误信息如下:
POST https://mySite.vercel.app/api 405 (Method Not Allowed) error in cart async: V {message: 'Request failed with status code 405', name: 'AxiosError', code: 'ERR_BAD_REQUEST', config: {…}, request: XMLHttpRequest, …}
客户端API调用代码:
const checkout = async () => { try { const totalCost = cartItems.reduce((total, item) => total + item.product.price, 0); const items=stringifyCart() const response = await axios.post('/api',{cartItems: items, totalCost: totalCost}, { headers: {'Content-Type': 'application/json'}}); window.location.href = response.data.url; } catch (error) { console.error("error in cart async: ", error); alert('Something went wrong during checkout'); } };
服务器端api/route.js代码:
const client = new Client({ accessToken: process.env.SQUARE_ACCESS_TOKEN, environment: Environment.Production }); export async function POST(req, res) { try { const { cartItems, totalCost, address } = await req.json(); const response = await client.checkoutApi.createPaymentLink({ idempotencyKey: new Date().getTime().toString(), quickPay: { name: cartItems, priceMoney: { amount: totalCost * 100, currency: 'USD' }, locationId: process.env.SQUARE_LOCATION_ID }, checkoutOptions: { askForShippingAddress: true, acceptedPaymentMethods: { applePay: true, googlePay: true, cashAppPay: true, afterpayClearpay: true } } }); return NextResponse.json({ url: response.result.paymentLink.url }, { status: 200 }); } catch (error) { console.error(error); return NextResponse.json({ error: error.message }, { status: 500 }); } };
1. 修正Next.js路由目录结构
如果使用Next.js App Router,API路由文件必须放在app/api/目录下,即路径应为app/api/route.js,而非根目录下的api/route.js。目录位置错误会导致Vercel无法识别API端点,直接返回405。
如果使用Next.js Pages Router,API文件需放在pages/api/目录下并命名为index.js,同时按Pages Router规范编写处理函数:
export default async function handler(req, res) { if (req.method !== 'POST') { res.setHeader('Allow', ['POST']); return res.status(405).end(`Method ${req.method} Not Allowed`); } // 原POST逻辑代码 }
2. 补充必要的导入语句
App Router的route.js中必须导入NextResponse才能正确返回响应,否则部署后函数执行失败会间接引发405错误。同时需确保Square相关依赖已导入:
import { NextResponse } from 'next/server'; import { Client, Environment } from 'square';
3. 处理GitHub Pages的静态托管限制
GitHub Pages仅支持静态文件托管,无法运行Next.js的服务器端API路由代码。若要部署到GitHub Pages,需将API部分单独部署到Vercel、Netlify Functions等支持Serverless的平台,然后修改客户端请求地址为API的完整URL:
const response = await axios.post('https://your-api-deployment.vercel.app/api', { cartItems: items, totalCost: totalCost }, { headers: {'Content-Type': 'application/json'} });
4. 验证Vercel环境变量配置
在Vercel项目的Settings > Environment Variables中确认SQUARE_ACCESS_TOKEN和SQUARE_LOCATION_ID已正确设置并同步到部署环境。虽然这不会直接导致405,但变量缺失会引发API函数内部错误,需一并排查。
5. 确认请求方法与路由匹配
客户端请求明确使用POST方法,服务器端仅需导出POST函数即可(App Router中未导出的方法会自动返回405),无需额外添加其他方法的处理逻辑。
内容的提问来源于stack exchange,提问作者Baxter John

