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:
httpvshttps - Domain:
dev.lovrabet.comvsapi.lovrabet.com - Port:
80vs443vs3000
CORS Examples
| Frontend URL | API URL | Cross-Origin? | Description |
|---|---|---|---|
http://localhost:3000 | https://api.lovrabet.com | Cross-origin | Protocol, domain, and port all differ |
https://dev.lovrabet.com | https://api.lovrabet.com | Cross-origin | Different domain (although both are lovrabet.com subdomains) |
https://dev.lovrabet.com | https://dev.lovrabet.com | Same-origin | Exactly the same domain |
http://example.com:80 | http://example.com:443 | Cross-origin | Different ports |
https://example.com | http://example.com | Cross-origin | Different 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:
| Solution | Use Case | Pros | Cons |
|---|---|---|---|
| Solution 1: Use dev.lovrabet.com | Development phase | Auto-configured, no extra setup needed | Development environment only |
| Solution 2: Server CORS Configuration | Need to access own API | Simple and direct | Requires server permissions |
| Solution 3: Server Forwarding | Complex business scenarios | Flexible and controllable, can add business logic | Requires additional development |
| Solution 4: Independent Deployment | Production environment | Fully autonomous, no CORS issues | Requires deployment resources |
Solution 1: Use dev.lovrabet.com Development Domain (Recommended)
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.comis 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.comdomain - If accessing non-
*.lovrabet.comAPIs, 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 Phase | Recommended Solution | Description |
|---|---|---|
| Local Development | Solution 1: dev.lovrabet.com | Zero configuration, works out of the box |
| Need to Access Own API | Solution 2: Server CORS | Simple and direct, good performance |
| Complex Business Scenarios | Solution 3: Server Forwarding | Flexible and controllable, powerful features |
| Production Environment | Solution 4: Independent Deployment | Fully 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.