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

Stripe跳转出现CORS错误,疑与Redux中localStorage存储有关求解决

Stripe支付跳转时CORS请求失败问题

错误信息

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource 
at http://localhost:5000/api/stripe/create-checkout-session. (Reason: CORS request did not 
succeed). Status code: (null).

已尝试的解决方法

  • 调整服务器CORS配置
  • 移除Redux切片中的localStorage操作
  • 前端直接发起请求(不依赖Redux)

问题仍未解决,怀疑错误与Redux中使用localStorage存储数组数据有关,需要可行的解决方法。

相关代码

Redux购物车切片代码

import { createSlice } from '@reduxjs/toolkit'

//stores products in local storage
const items = localStorage.getItem('products') !== null ? JSON.parse(localStorage.getItem('products')) : [];

//Empty cart to start
const initialState = {
  products: items,
  totalQuantity: 0,
  totalAmount: 0,
};

export const cartSlice = createSlice({
  name: 'cart',
  //State grabbed from above
  initialState,
 
  reducers: {

    addToCart: (state, action) => {
      //grabs item id from array and assigns it to payload
      const item = state.products.find(item => item.id === action.payload.id);

      if (item) {
        //increments payload quantity
        item.quantity += action.payload.quantity
        //total quantity assigned to payload
        state.totalQuantity += action.payload.quantity;
        //total price
        state.totalAmount += (action.payload.price  * action.payload.quantity);
      }
      else {
        //pushes items to reducer array
        state.products.push({
          id: action.payload.id,
          title: action.payload.title,
          img: action.payload.img,
          price: action.payload.price,
          count: action.payload.count,
        });
        //Grabs items from local storage
        localStorage.setItem('products', JSON.stringify(state.products));
        //increments quantity
        state.totalQuantity += action.payload.quantity;
        //total price
        state.totalAmount += ((action.payload.price) * action.payload.quantity);
      }
    },

    removeItem: (state, action) => {
      //Grabs index of item from data array
      const itemIndex = state.products.findIndex(item => item.id === action.payload);
      if (itemIndex !== -1) {
        const item = state.products[itemIndex];
        //decrements item quantity
        state.totalQuantity -= item.quantity;
        //decrements price 
        state.totalAmount -= item.price * item.quantity;
        //Removes item from array
        state.products.splice(itemIndex, 1);
        //Grabs item from local storage
        localStorage.setItem('products', JSON.stringify(state.products));
      }
      //No items in cart
      if (state.products.length === 0) {
        state.totalQuantity = 0;
        state.totalAmount = 0;
      }
  },
    updateCount: (state, action) => {
      //Finds item ID in array
        const item = state.products.find(item => item.id === action.payload.id);
        if (item) {
          //changes quantity
          const countDiff = action.payload.count - item.count;
          //Assigns item  count to payload
          item.count = action.payload.count;
          //Total item quantity in payload
          state.totalQuantity += countDiff;
          //Total price 
          state.totalAmount += item.price * countDiff;
        }
      },
  },
})


// Action creators are generated for each case reducer function
export const { addToCart, removeItem, resetCart, updateCount} = cartSlice.actions

export default cartSlice.reducer

Stripe支付按钮组件代码

import React from 'react';
import axios from 'axios';
import { useSelector } from 'react-redux';

const url = "http://localhost:5000/api";

const PayButton = ({cartItems}) => {
    console.log(cartItems)
    const handleCheckout = () => {
    axios.post(`${url}/stripe/create-checkout-session`, {
        cartItems,
        //put user _id from backend get request here
    }).then((res) => {
        if (res.data.url) {
            window.location.href = res.data.url;
        }
    }).catch ((error) => {
        console.log(error.message)
    })
    }

  return (
    <>
    <button onClick={() => handleCheckout()}>Check Out</button>
    </>
  )
}

export default PayButton

Stripe后端路由代码

const express = require('express');
const app = express();
const stripe = require('stripe')(process.env.STRIPE_KEY);
require('dotenv').config();

const router = express.Router();

//grabs cart from cart items component

router.post('/create-checkout-session', async (req, res) => {
  const cartItems = req.body.cartItems;
  const lineItems = cartItems.map((item) => {
    return {
      price_data: {
        currency: 'usd',
        product_data: {
          name: item.title,
          images: [item.img],
        },
        unit_amount: parseFloat(item.price) * 100,
      },
      quantity: item.count,
    };
  });


  const session = await stripe.checkout.sessions.create({
    billing_address_collection: 'required',
    shipping_address_collection: {
      allowed_countries: ['US', 'CA'],
    },
    line_items: lineItems,
    mode: 'payment',
    success_url: `${process.env.WEB_APP_URL}/checkout-success`,
    cancel_url: `${process.env.WEB_APP_URL}/cart`,
  });

  res.send({url: session.url});
});


module.exports = router;

期望结果

点击"Check Out"按钮后能正常跳转至Stripe支付页面。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 00:54:54