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

Flask+Stripe表单提交后跳转支付页遇CORS跨域问题求助

问题:跳转Stripe支付页时出现CORS跨域错误

背景

  • 目标:开发基于HTML、Bootstrap、JavaScript的网站,支持用户添加任意数量WTForms表单,提交后由Flask后端验证并存入数据库,最终跳转至Stripe托管的支付页面。
  • 已完成:实现用户填写任意数量表单并以JSON列表提交至后端,后端转换为WTForms验证并存入数据库的功能。
  • 遇到的错误:

Access to fetch at 'https://checkout.stripe.com/c/pay/cs_test_a1SrbQBbElmNFdfuSsF...' (redirected from 'http://localhost:4242/test') from origin 'http://localhost:4242' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

问题根源

你用fetch发起AJAX请求到后端/test接口,后端返回302重定向到Stripe的支付URL。此时fetch会自动跟随重定向,向Stripe的地址发起请求,但Stripe的服务器不会为localhost:4242设置Access-Control-Allow-Origin头,浏览器出于安全策略拦截了这个跨域请求,导致CORS错误。

解决方法

方案1:后端返回Stripe支付URL,前端主动跳转

修改后端,不再返回重定向,而是直接返回Stripe的支付URL;前端拿到URL后用window.location.href跳转,绕开AJAX的CORS限制。

后端修改(create_checkout_session和test接口):

# 修改create_checkout_session,返回JSON格式的URL
@app.route('/create_checkout_session', methods=["GET", "POST"])
def create_checkout_session():
    try:
        product_id = session.get('product_id')
        domain_url = os.getenv('DOMAIN')

        checkout_session = stripe.checkout.Session.create(
            line_items=[
                {
                    'price': product_id,
                    'quantity': 1,
                },
            ],
            mode='subscription',
            success_url=domain_url + url_for('success'),
            cancel_url=domain_url + '/cancel',
        )
        # 返回JSON格式的支付URL
        return {'url': checkout_session.url}
    except Exception as e:
        return {'error': str(e)}, 400

# 修改test接口,返回create_checkout_session的结果
@app.route('/test', methods=["GET", "POST"])
def test():
    if request.method == "POST":
        # ... 原有验证逻辑保持不变 ...
        
        if validForms:
            # 不再重定向,而是调用create_checkout_session获取URL并返回
            checkout_response = create_checkout_session()
            return checkout_response
    
    test_form = TestForm()
    return render_template("test.html", form=test_form)

前端修改:

fetch('/test', {
  method: 'POST',
  body: JSON.stringify(wholeJson),
  headers: {
    'Content-Type': 'application/json'
  }
}).then(response => {
  if (response.ok) {
    return response.json(); // 解析后端返回的JSON
  } else {
    throw new Error('Server error');
  }
}).then(data => {
  if (data.url) {
    window.location.href = data.url; // 直接跳转至Stripe支付页
  } else {
    console.error('Error:', data.error);
  }
}).catch(error => {
  console.error('Error:', error);
});

方案2:改用普通表单提交(更简便)

放弃AJAX请求,直接用HTML表单提交数据。因为浏览器处理表单提交的重定向不受CORS限制,后端返回的302重定向会直接让页面跳转,不会触发AJAX的跨域检查。

前端修改:

把收集到的表单数据隐藏在一个表单里,点击按钮时提交这个表单:

<!-- 在页面中添加一个隐藏表单 -->
<form id="hidden-form" method="POST" action="/test">
  <input type="hidden" id="form-data" name="form_data">
</form>

<script>
document.addEventListener('DOMContentLoaded', () => {
  var button = document.getElementById('submit');    
  button.addEventListener('click', event => {
    event.preventDefault(); // 阻止原有按钮的默认行为
    var wholeJson = {};
    // ... 原有收集表单数据的逻辑保持不变 ...
    
    // 将JSON数据转为字符串,放入隐藏字段
    document.getElementById('form-data').value = JSON.stringify(wholeJson);
    // 提交隐藏表单
    document.getElementById('hidden-form').submit();
  });
});
</script>

后端修改:

修改test接口,从表单字段中获取JSON数据:

import json

@app.route('/test', methods=["GET", "POST"])
def test():
    if request.method == "POST":
        # 从表单字段获取JSON数据
        whole_json = json.loads(request.form.get('form_data'))
        product_name : str = whole_json['product_name']
        # ... 后续验证逻辑保持不变 ...
        
        if validForms:
            return redirect(url_for('create_checkout_session'))
    
    test_form = TestForm()
    return render_template("test.html", form=test_form)

总结

方案2更简便,不需要修改Stripe相关的后端逻辑,直接利用浏览器原生的表单提交机制避开CORS问题;方案1适合需要保留AJAX交互的场景。

内容的提问来源于stack exchange,提问作者monre

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 20:21:09