Skip to main content

Frontend CORS Solutions

During frontend development, Cross-Origin Resource Sharing (CORS) is a common issue. This document introduces various solutions for resolving CORS issues in projects created with Lovrabet CLI.

What Is the CORS Issue?

CORS refers to the browser's security restriction that limits a web page from one domain from requesting resources from another domain. When the protocol, domain, or port differs, a CORS issue occurs.

Important Note: Even if both are *.lovrabet.com subdomains, dev.lovrabet.com and api.lovrabet.com are still different domains and belong to cross-origin requests. It's just that by configuring a CORS whitelist, this type of cross-origin access is allowed.

CORS Criteria

Browsers determine whether a request is cross-origin based on whether these three elements are exactly the same:

  • Protocol: http vs https
  • Domain: dev.lovrabet.com vs api.lovrabet.com
  • Port: 80 vs 443 vs 3000

CORS Examples

Frontend URLAPI URLCross-Origin?Description
http://localhost:3000https://api.lovrabet.comCross-originProtocol, domain, and port all differ
https://dev.lovrabet.comhttps://api.lovrabet.comCross-originDifferent domain (although both are lovrabet.com subdomains)
https://dev.lovrabet.comhttps://dev.lovrabet.comSame-originExactly the same domain
http://example.com:80http://example.com:443Cross-originDifferent ports
https://example.comhttp://example.comCross-originDifferent protocols

Note: dev.lovrabet.com -> api.lovrabet.com although both are lovrabet.com subdomains, they are still cross-origin. It's just that by configuring a CORS whitelist on the server side, cross-origin requests from dev.lovrabet.com are allowed, so no CORS error occurs.

Solutions Overview

Lovrabet CLI provides multiple solutions for CORS issues. You can choose based on your actual scenario:

SolutionUse CaseProsCons
Solution 1: Use dev.lovrabet.comDevelopment phaseAuto-configured, no extra setup neededDevelopment environment only
Solution 2: Server CORS ConfigurationNeed to access own APISimple and directRequires server permissions
Solution 3: Server ForwardingComplex business scenariosFlexible and controllable, can add business logicRequires additional development
Solution 4: Independent DeploymentProduction environmentFully autonomous, no CORS issuesRequires deployment resources

How It Works

When using lovrabet start to launch your project, the CLI automatically maps your local project to the dev.lovrabet.com development domain.

Important: Although dev.lovrabet.com and api.lovrabet.com are both lovrabet.com subdomains, they are still different domains and belong to cross-origin requests. It's just that dev.lovrabet.com has been added to the Lovrabet platform's CORS whitelist, and the server side allows cross-origin requests from dev.lovrabet.com, so no CORS error occurs.

How to Use

# Start development server
lovrabet start

# Access URL will be automatically mapped to
# https://dev.lovrabet.com/your-app-path

Advantages

  • Zero configuration: Works out of the box without any additional setup
  • Auto mapping: CLI automatically handles domain mapping and HTTPS
  • Whitelist configured: dev.lovrabet.com is already in the CORS whitelist
  • Development friendly: Supports hot reload for smooth development experience

Notes

  • This solution only applies to development environment
  • Need to log in to Lovrabet platform to use the dev.lovrabet.com domain
  • If accessing non-*.lovrabet.com APIs, CORS issues may still occur

Solution 2: Server CORS Configuration

Applicable Scenarios

When your frontend application runs on dev.lovrabet.com but needs to access your own server's API, you may encounter CORS issues. In this case, you can configure CORS on your server to allow access from dev.lovrabet.com.

Configuration Examples

Node.js (Express)

const express = require('express');
const app = express();

// Allow dev.lovrabet.com cross-origin access
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', 'https://dev.lovrabet.com');
res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization');
res.header('Access-Control-Allow-Credentials', 'true');

if (req.method === 'OPTIONS') {
return res.sendStatus(200);
}
next();
});

Nginx

server {
listen 80;
server_name your-api-domain.com;

location / {
# Allow dev.lovrabet.com cross-origin access
add_header 'Access-Control-Allow-Origin' 'https://dev.lovrabet.com';
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization';
add_header 'Access-Control-Allow-Credentials' 'true';

if ($request_method = 'OPTIONS') {
return 204;
}

# Your API processing logic
proxy_pass http://backend;
}
}

Spring Boot (Java)

@Configuration
public class CorsConfig {
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("https://dev.lovrabet.com")
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
.allowedHeaders("*")
.allowCredentials(true);
}
};
}
}

Advantages

  • Simple and direct: Just need one-time server-side configuration
  • Good performance: Browser accesses API directly, no intermediate layer
  • Flexible: Can precisely control allowed domains and methods

Notes

  • Requires server administrator permissions
  • For production environment, recommend using environment variables to configure allowed domains
  • Pay attention to security, don't use wildcard * to allow all domains

Solution 3: Server Request Forwarding (API Proxy)

Applicable Scenarios

When you can't modify server CORS configuration, or need to add business logic, permission validation, or data transformation in requests, you can use the server forwarding solution.

How It Works

The frontend doesn't call the target API directly, but calls its own server interface, which forwards the request to the target API. This allows:

  • Bypass browser CORS restrictions
  • Add business logic on the server side
  • Hide API implementation details
  • Unified error handling and logging

Implementation Examples

Refer to Next.js Demo Project Scenario 3: API Proxy Solution.

Next.js API Route Example

// app/api/proxy/data/route.ts
import { NextRequest, NextResponse } from "next/server";
import { createServerClient } from "@/lib/sdk-client";

export async function GET(request: NextRequest) {
try {
const searchParams = request.nextUrl.searchParams;
const page = searchParams.get("page") || "1";
const size = searchParams.get("size") || "10";

// Create client on server side (no CORS issues)
const client = createServerClient();
const model = client.getModel(0);

// Call SDK to get data
const response = await model.filter({
page: parseInt(page),
pageSize: parseInt(size),
});

// Return data to frontend
return NextResponse.json({
success: true,
data: response,
});
} catch (error) {
return NextResponse.json(
{
success: false,
error: error instanceof Error ? error.message : "Unknown error",
},
{ status: 500 }
);
}
}

Frontend Call

// Frontend gets data through its own API route
const fetchData = async () => {
const response = await fetch('/api/proxy/data?page=1&size=10');
const result = await response.json();

if (result.success) {
// Use data
console.log(result.data);
}
};

Express.js Example

const express = require('express');
const axios = require('axios');
const app = express();

app.use(express.json());

// Proxy API requests
app.get('/api/proxy/data', async (req, res) => {
try {
const { page, size } = req.query;

// Call target API on server side (no CORS restrictions)
const response = await axios.get('https://api.target.com/data', {
params: { page, size },
headers: {
'Authorization': `Bearer ${process.env.API_TOKEN}`,
},
});

// Can add business logic, data transformation here
const transformedData = transformData(response.data);

res.json({
success: true,
data: transformedData,
});
} catch (error) {
res.status(500).json({
success: false,
error: error.message,
});
}
});

function transformData(data) {
// Data transformation logic
return data;
}

Advantages

  • Completely bypasses CORS: No CORS restrictions on server side
  • Flexible and controllable: Can add business logic, permission validation
  • Hide implementation: Frontend doesn't need to know target API details
  • Unified handling: Can unify error handling, logging, caching, etc.

Notes

  • Requires additional server resources
  • Adds request chain, may have slight delay
  • Need to handle server-side errors and timeouts

Complete Example

For complete implementation examples, see the scenario3-proxy scenario in the openapi-nextjs-demo project.


Solution 4: Independent Deployment to Your Own Server

Applicable Scenarios

After development is complete, deploy the project independently to your server using your own domain. This way there won't be CORS issues because both frontend and API are under your control.

Deployment Steps

1. Build Production Version

# Build project
lovrabet build

# Build output is in dist/ directory

2. Deploy to Server

Deploy the contents of the dist/ directory to your web server (Nginx, Apache, CDN, etc.).

3. Configure Domain and HTTPS

# Nginx configuration example
server {
listen 80;
server_name your-domain.com;

# Redirect to HTTPS
return 301 https://$server_name$request_uri;
}

server {
listen 443 ssl;
server_name your-domain.com;

ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;

root /path/to/dist;
index index.html;

location / {
try_files $uri $uri/ /index.html;
}
}

4. Configure API Address

Set the production environment API address in project configuration:

// .env.production
VITE_API_BASE_URL=https://api.your-domain.com

Advantages

  • Fully autonomous: Complete control over frontend and API
  • No CORS issues: Same domain or CORS already configured
  • Best performance: Direct access, no intermediate layer
  • Production ready: Suitable for production environment

Notes

  • Requires server resources and domain name
  • Need to configure HTTPS certificate
  • Need to handle routing and static assets
  • Recommend using CDN to accelerate static assets

Solution Selection Guide

Choose the appropriate solution based on your actual scenario:

Development PhaseRecommended SolutionDescription
Local DevelopmentSolution 1: dev.lovrabet.comZero configuration, works out of the box
Need to Access Own APISolution 2: Server CORSSimple and direct, good performance
Complex Business ScenariosSolution 3: Server ForwardingFlexible and controllable, powerful features
Production EnvironmentSolution 4: Independent DeploymentFully autonomous, best performance

Common Issues

Q: Why doesn't using dev.lovrabet.com have CORS issues?

A: Actually, dev.lovrabet.com and api.lovrabet.com are still cross-origin (because domains are different). But dev.lovrabet.com has been added to the Lovrabet platform's CORS whitelist, and the server side is configured to allow cross-origin requests from dev.lovrabet.com, so the browser doesn't block these requests, making it seem like there's no CORS issue.

Q: Can I develop on localhost?

A: Yes, but localhost is not in the CORS whitelist, so accessing *.lovrabet.com APIs will result in CORS issues. It's recommended to use dev.lovrabet.com for development.

Q: Must I deploy independently for production?

A: Not necessarily. If your frontend and API are under the same domain, or CORS is already configured, you can deploy directly. But independent deployment is usually more flexible and secure.

Q: Will server forwarding affect performance?

A: There will be a slight impact because it adds to the request chain. But for most applications, this impact is negligible. If you have extremely high performance requirements, consider using Solution 2 or Solution 4.