Netlify集成Stripe Checkout报错“Bad request, missing form”求助
问题描述
我正尝试将Stripe Checkout集成到已上线的Netlify网站中,但代码的服务端与客户端均未正常运行,返回“Bad request, missing form”响应,似乎无法接收POST请求。我已配置netlify.toml和_redirect文件,本地环境可正常运行,但部署后功能失效,该如何解决?
相关代码
checkout.js
const button = document.getElementById("checkout-button") button.addEventListener("click", () => { fetch('/create-checkout-session', { method: 'POST', headers: { "Content-Type": "application/json" }, body: JSON.stringify({ // items: [{ id: "Black Sweatsuit"}, // { id: "Grey Sweatsuit"}, // { id: "Red Sweatsuit"}, // { id: "Blue Sweatsuit"}, // { id: "Black T-Shirt"}, // { id: "Blue T-Shirt"}, // { id: "Purple T-Shirt"} // ], }), }) .then(res => { if (res.ok) return res.json() return res.json().then(json => Promise.reject(json)) }) .then(({ url }) => { window.location = url }) .catch(e => { console.error(e.error) }) })
server.js
const stripe = require('stripe')('sk_live_XXXXXXX') const express = require('express') const app = express() app.use(express.static('public')) app.use(express.json()) const YOUR_DOMAIN = 'http://www.kimiee-kreates.com'; const storeItems = new Map([ [1, { priceId: 'price_XXXX', name: "El Chapo"}], [2, { priceId: 'price_XXXX', name: "Joker"}], [3, { priceId: 'price_XXXX', name: "Joker"}], [4, { priceId: 'price_XXXX', name: "She Hit Different"}], [5, { priceId: 'price_XXXX', name: "Icy Girl"}], [6, { priceId: 'price_XXXX', name: "Girls don't Cry"}], [7, { priceId: 'price_XXXX', name: "Black Kaws"}], [8, { priceId: 'price_XXXX', name: "Orange Kaws"}], [9, { priceId: 'price_XXXX', name: "Scarface Monoly"}], [10, { priceId: 'price_XXXX',name: "Run, Rick & Morty"}], [11, { priceId: 'price_XXXX', name: "Glo Sun"}], [12, { priceId: 'price_XXXX', name: "Child's Play"}], [13, { priceId: 'price_XXXX', name: "Scream"}], [14, { priceId: 'price_XXXX', name: "Vegeta - Blue & Black"}], [15, { priceId: 'price_XXXX', name: "Goku"}], [16, { priceId: 'price_XXXX', name: "Juice"}], [17, { priceId: 'price_XXXX', name: "Rick & Morty"}], [18, { priceId: 'price_XXXX', name: "Vegeta"}], ]) app.post('/create-checkout-session', async (req, res) => { const session = await stripe.checkout.sessions.create({ line_items: [ { price:'price_1M334EJGTDSvYp0wR4rUafhO', quantity: 1, adjustable_quantity: { enabled: true, } }, { price:'price_1M334MJGTDSvYp0wRqy65q46', quantity: 1, adjustable_quantity: { enabled: true, } }, ], payment_method_types: ['card'], mode: 'payment', success_url: `${YOUR_DOMAIN}/success.html`, cancel_url: `${YOUR_DOMAIN}/cancel.html`, automatic_tax: {enabled: true}, }); res.redirect(303, session.url); });
解决方案
1. 改用Netlify Functions部署后端逻辑
Netlify不支持直接运行常规Express服务器,必须将后端接口改成Netlify无服务器函数:
- 在项目根目录创建
netlify/functions文件夹 - 将
server.js中的结账逻辑提取为单独函数文件netlify/functions/create-checkout-session.js:
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY); // 用环境变量存密钥,禁止硬编码 exports.handler = async (event) => { // 仅处理POST请求 if (event.httpMethod !== 'POST') { return { statusCode: 405, body: JSON.stringify({ error: 'Method not allowed' }) }; } try { const session = await stripe.checkout.sessions.create({ line_items: [ { price:'price_1M334EJGTDSvYp0wR4rUafhO', quantity: 1, adjustable_quantity: { enabled: true } }, { price:'price_1M334MJGTDSvYp0wRqy65q46', quantity: 1, adjustable_quantity: { enabled: true } }, ], payment_method_types: ['card'], mode: 'payment', success_url: `${process.env.YOUR_DOMAIN}/success.html`, cancel_url: `${process.env.YOUR_DOMAIN}/cancel.html`, automatic_tax: { enabled: true }, }); return { statusCode: 303, headers: { Location: session.url }, body: '' }; } catch (error) { return { statusCode: 500, body: JSON.stringify({ error: error.message }) }; } };
2. 修改客户端请求路径
Netlify Functions的访问路径格式为/.netlify/functions/[函数名],更新checkout.js中的fetch地址:
fetch('/.netlify/functions/create-checkout-session', { // 其余代码保持不变 })
3. 配置Netlify环境变量
在Netlify后台的「项目设置 → 环境变量」中添加:
STRIPE_SECRET_KEY:你的Stripe生产秘钥(sk_live_xxx)YOUR_DOMAIN:网站的HTTPS域名(Netlify部署的站点默认启用HTTPS,不要用HTTP)
4. 修复客户端响应处理逻辑
服务端返回303重定向,客户端原来的JSON解析逻辑会报错,调整为:
.then(res => { if (res.redirected) { window.location = res.url; return; } if (res.ok) return res.json(); return res.json().then(json => Promise.reject(json)); }) // 删除原来的.then(({url}) => window.location = url)
5. 检查Netlify配置文件
确保netlify.toml配置正确,无需额外重定向规则(Netlify会自动处理Functions路径):
[build] command = "npm run build" # 替换为你的项目构建命令 publish = "public" # 你的静态文件目录 [[redirects]] from = "/*" to = "/index.html" status = 200
6. 排查"Bad request, missing form"错误
- 用Netlify后台的「Functions → 日志」查看请求详情,确认请求是否到达函数、请求体格式是否正确
- 确保客户端请求的
Content-Type为application/json(当前代码已设置) - 不要在代码中硬编码敏感信息,必须用环境变量
内容的提问来源于stack exchange,提问作者user16147870
相关产品推荐
相关产品推荐

