javascriptjavahtmlspring-bootcors

CORS issue, Cross origin error in spring boot. How do I allow CORS


I have a very pertinent issue. I built this JavaScript based on a python script that tests my server which works fine. My issue is that when I click on subscribe in the front end, I'm met with a Cors error which I never had before. look at the image. Any help is greatly welcomed and appreciated. I have to use CORS because I'm running two servers and one calls and seeks information from the other.

The image shows the error

document.getElementById('payment-form').addEventListener('submit', async function(event) {
  event.preventDefault(); // Prevent default form submission

  // Base URL for the server running on port 4242
  const baseUrl = "http://localhost:4242";

  try {
    // Step 1: Get config data
    const configResponse = await fetch(`${baseUrl}/config`, {
      method: 'GET',
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json' // Ensure correct content type
      }
    });

    if (!configResponse.ok) {
      throw new Error(`Failed to fetch config: ${configResponse.statusText}`);
    }

    const configData = await configResponse.json();

    // Step 2: Create a checkout session
    const checkoutSessionResponse = await fetch(`${baseUrl}/create-checkout-session`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Accept': 'application/json'
      },
      body: JSON.stringify({
        priceId: configData.proPrice
      })
    });

    if (!checkoutSessionResponse.ok) {
      throw new Error(`Failed to create checkout session: ${checkoutSessionResponse.statusText}`);
    }

    // Step 3: Handle the checkout session response
    const checkoutSessionUrl = checkoutSessionResponse.headers.get('Location');

    if (checkoutSessionUrl) {
      const sessionIdPattern = /cs_test_\w+/;
      const match = checkoutSessionUrl.match(sessionIdPattern);

      if (match) {
        const checkoutSessionId = match[0];
        console.log("Checkout Session ID:", checkoutSessionId);

        // Step 4: Redirect the user to the Stripe checkout
        window.location.href = checkoutSessionUrl;
      } else {
        throw new Error("Failed to extract Checkout Session ID from the URL");
      }
    } else {
      throw new Error("No Location header found in the response");
    }
  } catch (error) {
    // Error handling: log error and notify the user
    console.error("Error:", error);
    alert(`An error occurred: ${error.message}`);
  }
});
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Checkout</title>
  <link rel="stylesheet" href="/css/checkout.css">
</head>

<body>
  <div class="container">
    <div class="features">

      <h3>Try Columbaria</h3>
      <h1>3 days free Then $2.00/month</h1>
      <p>Features include Mobile device touchpad, Tablet/iPad touchpad, hand gesture tracking, up to 5 people viewing, Weekend support</p>
      <div class="icon">
        <img src="/images/icon.png" alt="Wi-Fi Icon">
      </div>
    </div>
    <div class="payment">
      <h2>Payment</h2>
      <form id="payment-form" class="payment-form" action="/create-checkout-session">
        <div class="form-group">
          <label for="card-number">Card Number</label>
          <input type="text" id="card-number" placeholder="1234-1234-1234-1234" required>
        </div>
        <div class="form-group">
          <label for="expiry-date">Expiration Date (MM/YY)</label>
          <input type="text" id="expiry-date" placeholder="MM/YY" required>
        </div>
        <div class="form-group">
          <label for="cvc">CVC</label>
          <input type="text" id="cvc" placeholder="CVC" required>
        </div>
        <div class="form-group">
          <label for="cardholder-name">Cardholder Name</label>
          <input type="text" id="cardholder-name" placeholder="Full name on card" required>
        </div>
        <div class="form-group">
          <label for="country">Country</label>
          <select id="country" required>
          </select>
          <script>
            const countries = [{
                code: "US",
                name: "United States"
              },
              {
                code: "CA",
                name: "Canada"
              },
              {
                code: "GB",
                name: "United Kingdom"
              },
              {
                code: "AU",
                name: "Australia"
              },
              {
                code: "DE",
                name: "Germany"
              },
              {
                code: "FR",
                name: "France"
              },
              {
                code: "IN",
                name: "India"
              },
              {
                code: "CN",
                name: "China"
              },
              {
                code: "JP",
                name: "Japan"
              },
            ];

            const countrySelect = document.getElementById('country');

            countries.forEach(country => {
              const option = document.createElement('option');
              option.value = country.code;
              option.textContent = country.name;
              countrySelect.appendChild(option);
            });
          </script>
        </div>
        <div class="form-group">
          <label for="zip-code">Zip Code</label>
          <input type="text" id="zip-code" placeholder="Zip Code" required>
        </div>
        <div class="form-group">
          <input type="checkbox" id="save-info">
          <label for="save-info">Save my info for 1-click checkout</label>
        </div>
        <button id="payment-form-sub" class="payment-form-sub" type="submit">Subscribe</button>
      </form>
    </div>
  </div>
  <script src="/scripts/checkout.js"></script>
</body>

</html>

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class CorsConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("https://mywebsite.com", "https://localhost:8443") // Combine origins
                .allowedMethods("GET", "POST", "PUT", "DELETE")
                .allowedHeaders("*")
                .allowCredentials(true);
    }

    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        config.addAllowedOrigin("https://mywebsite.com");
        config.addAllowedOrigin("https://localhost:8443");
        config.addAllowedHeader("*");
        config.addAllowedMethod("*");
        source.registerCorsConfiguration("/**", config);

        return new CorsFilter(source);
    }
}

Solution

  • if you see this, just use a cors blocker for your local host, then you can set up a cors proxy on your own server. do not use no cors if you plan to use the results in the response.