本地环境后端跳转至Stripe时如何规避CORS错误?
问题描述
我们正在为系统集成Stripe支付服务,现有Angular应用允许用户选择商品购买,调用API创建支付会话的前端代码如下:
createPaymentSession(products: Array<number>, subscription: number) { return this.http.post<Response<any>>( this.baseUrl + 'shopping/payment', { products, subscription } ); }
后端创建结账流程后,会跳转至生成的Stripe结账URL,后端代码如下:
[HttpPost("payment")] public async Task<IActionResult> CreatePayment(CreateCheckoutRequest request) { var session = await _serviceProvider.GetRequiredService<ICommerceService>().CreatePaymentSession(request.Products, request.Subscription); if (session is not null) { return Redirect(session.Url); } return Ok(); }
整体流程可正常运行,但在localhost环境测试时出现CORS错误:
Access to XMLHttpRequest at 'https://checkout.stripe.com/c/pay/cs_test_...' (redirected from 'http://localhost:5004/api/shopping/payment') from origin 'http://localhost:4200' 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.
如何解决该错误以完成本地环境测试?
补充:Stripe官方文档中的ASP.NET MVC实现示例:
// 此示例使用ASP.NET MVC框架搭建端点 // 观看视频快速上手:https://youtu.be/2-mMOB8MhmE using System.Collections.Generic; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Options; using Stripe; using Stripe.Checkout; namespace server.Controllers { public class PaymentsController : Controller { public PaymentsController() { StripeConfiguration.ApiKey = "sk_test_51NAu5ZGVj6xdB6Xmzpl8nniTmtbLiLoGa3IAlTGPu3nsrZ4FsWgL7fnBL3A4CmhMgbQD7cIIuSNR3xkNhesWKMd2003DoZ5MQA"; } [HttpPost("create-checkout-session")] public ActionResult CreateCheckoutSession() { var options = new SessionCreateOptions { LineItems = new List<SessionLineItemOptions> { new SessionLineItemOptions { PriceData = new SessionLineItemPriceDataOptions { UnitAmount = 2000, Currency = "usd", ProductData = new SessionLineItemPriceDataProductDataOptions { Name = "T-shirt", }, }, Quantity = 1, }, }, Mode = "payment", SuccessUrl = "http://localhost:4242/success", CancelUrl = "http://localhost:4242/cancel", }; var service = new SessionService(); Session session = service.Create(options); Response.Headers.Add("Location", session.Url); return new StatusCodeResult(303); } } }
解决方案
问题核心是:前端通过AJAX请求后端接口,后端返回3xx跳转至Stripe结账页,但Stripe域名不会给localhost添加CORS头,导致浏览器拦截跨域跳转。以下是两种可行的解决方式:
方法1:后端返回会话URL,前端主动跳转
不要让后端直接返回Redirect,而是将Stripe会话URL作为响应数据返回,由前端负责跳转,这也是Stripe推荐的AJAX场景最佳实践。
修改后端代码:
[HttpPost("payment")] public async Task<IActionResult> CreatePayment(CreateCheckoutRequest request) { var session = await _serviceProvider.GetRequiredService<ICommerceService>().CreatePaymentSession(request.Products, request.Subscription); if (session is not null) { // 返回会话URL而非直接跳转 return Ok(new { checkoutUrl = session.Url }); } return BadRequest("无法创建支付会话"); }
修改前端代码:
调用API获取URL后,通过window.location.href跳转:
createPaymentSession(products: Array<number>, subscription: number) { this.http.post<{ checkoutUrl: string }>( this.baseUrl + 'shopping/payment', { products, subscription } ).subscribe({ next: (response) => { // 跳转到Stripe结账页面 window.location.href = response.checkoutUrl; }, error: (err) => { console.error('创建支付会话失败', err); } }); }
方法2:本地环境启用HTTPS
Stripe要求支付流程使用HTTPS,本地HTTP环境可能加剧CORS问题,可为前后端都配置本地HTTPS:
- Angular启用HTTPS:启动项目时添加参数
ng serve --ssl true,或在angular.json中配置默认启用SSL。 - ASP.NET后端启用HTTPS:在
launchSettings.json中确保applicationUrl包含HTTPS地址(如https://localhost:5001)并启用SSL。
注:方法1是更可靠的解决方案,从根源上避免了跨域跳转问题。
内容的提问来源于stack exchange,提问作者Kęstutis Ramulionis
相关产品推荐
相关产品推荐

