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

React+Rails电商项目Stripe支付控制器跳转报错求助

Hey there! Let's break down what's going on with your React + Rails e-commerce setup and that tricky redirect issue with the Stripe charges controller. I’ve run into similar headaches with SPA-Rails integrations before, so let’s walk through the fixes step by step.

The Core Problem: AJAX + Rails Redirects Don’t Play Nice

When you send a fetch request (which is an AJAX call) to your charges#create action, Rails tries to redirect with redirect_to new_charge_path—but browsers don’t automatically handle this redirect for AJAX requests. Instead, the fetch call will receive the response from charges#new directly, but your React app isn’t set up to process that response, leading to errors.

Instead of having Rails handle the redirect, return a JSON response from create and let React manage the navigation or state update. This is the cleanest approach for single-page apps.

Update Your Rails ChargesController:

class ChargesController < ApplicationController
  def create
    begin
      # Process Stripe charge here
      charge = Stripe::Charge.create(
        amount: params[:amount],
        currency: 'usd',
        source: params[:stripe_token],
        description: params[:description]
      )

      # If successful, return success status and redirect URL
      render json: { status: :success, redirect_url: new_charge_path }, status: :ok
    rescue Stripe::CardError => e
      # Handle payment failures by returning errors
      @charge = Charge.new(charge_params)
      @charge.errors.add(:base, e.message)
      render json: { errors: @charge.errors.full_messages }, status: :unprocessable_entity
    end
  end

  def new
    @charge = Charge.new
    respond_to do |format|
      format.html
      format.json { render json: @charge } # Ensure JSON is supported here
    end
  end

  private
  def charge_params
    params.permit(:amount, :description, :stripe_token)
  end
end

Update Your React Fetch Logic:

Handle the JSON response to either redirect or display errors:

const handlePaymentSubmit = async (chargeData) => {
  try {
    const response = await fetch('/charges', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Accept': 'application/json',
        'X-CSRF-Token': document.querySelector('meta[name="csrf-token"]').content
      },
      body: JSON.stringify(chargeData)
    });

    const data = await response.json();

    if (data.status === 'success') {
      // Redirect to the new charge page (use React Router if it's an SPA route)
      window.location.href = data.redirect_url;
      // Or for React Router: history.push(data.redirect_url);
    } else {
      // Display error messages to the user
      alert(`Payment failed: ${data.errors.join(', ')}`);
    }
  } catch (error) {
    console.error('Request error:', error);
  }
};

Fix 2: If You Must Keep Rails Redirects (Not Ideal for SPAs)

If you need to stick with redirect_to, you’ll need to make sure fetch follows the redirect and your new action handles the request properly.

Ensure charges#new Responds to JSON:

def new
  # Pull parameters from session if you need to persist data across redirects
  @charge = Charge.new(session[:charge_params] || {})
  session.delete(:charge_params) # Clean up after use

  respond_to do |format|
    format.html
    format.json { render json: @charge }
  end
end

Update charges#create to Store Params in Session:

Since AJAX redirects don’t carry POST params, use the session to pass data to new:

def create
  @charge = Charge.new(charge_params)
  if @charge.invalid?
    session[:charge_params] = charge_params
    redirect_to new_charge_path, status: :see_other
  else
    # Process Stripe charge...
  end
end

Adjust Fetch to Handle Redirects:

Fetch follows redirects by default, but you’ll need to process the final response from charges#new:

fetch('/charges', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Accept': 'application/json',
    'X-CSRF-Token': document.querySelector('meta[name="csrf-token"]').content
  },
  body: JSON.stringify(chargeData)
})
.then(response => {
  // Check if we were redirected
  if (response.redirected) {
    return response.json(); // Get the new charge data from the redirected response
  }
  return response.json();
})
.then(data => {
  // Use the @charge data from charges#new to update your React state
  console.log('New charge data:', data);
})
.catch(error => console.error('Error:', error));

Quick Check for Nil Params

If your params are coming through as nil in charges#new, double-check:

  • You’re permitting all required parameters in charge_params
  • The React app is correctly stringifying the data in the fetch body
  • You’re using session[:charge_params] to persist data across redirects (if using that approach)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 07:26:01