You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
270 lines
7.7 KiB
Markdown
270 lines
7.7 KiB
Markdown
# CORS Issue - Web SignalR Connection & API Calls
|
|
|
|
## Problem
|
|
```
|
|
ClientException: Failed to fetch, uri=https://ms.hmg.com/nscapi/PatientCallingHub/negotiate?IPAddress=10.71.50.53
|
|
ClientException: Failed to fetch, uri=https://ms.hmg.com/nscapi/api/PatientCall/Common_Config_GetByIP
|
|
```
|
|
|
|
### What is CORS?
|
|
CORS (Cross-Origin Resource Sharing) is a browser security feature that blocks web apps from making requests to different domains unless the server explicitly allows it.
|
|
|
|
- ✅ **Mobile app**: Works fine (no CORS restrictions)
|
|
- ❌ **Web app**: Blocked by browser (CORS policy)
|
|
|
|
## Why This Happens
|
|
|
|
The web app is trying to connect to:
|
|
```
|
|
https://ms.hmg.com/nscapi/PatientCallingHub (SignalR Hub)
|
|
https://ms.hmg.com/nscapi/api/PatientCall/* (REST APIs)
|
|
https://ms.hmg.com/nscapi/api/Gen/* (Generic APIs)
|
|
https://ms.hmg.com/nscapi/api/Common/* (Common APIs)
|
|
```
|
|
|
|
But the browser blocks it because:
|
|
1. The web app is running on a different origin (e.g., `http://localhost:port` or `http://device-ip:port`)
|
|
2. The server (`ms.hmg.com`) doesn't send CORS headers allowing the web app's origin
|
|
|
|
**⚠️ IMPORTANT:** CORS must be configured for **ALL API endpoints**, not just SignalR!
|
|
|
|
## Solutions
|
|
|
|
### **Solution 1: Configure CORS on Server (RECOMMENDED)**
|
|
|
|
The backend server needs to add CORS headers to allow web requests. The server admin needs to configure:
|
|
|
|
#### For ASP.NET Core (SignalR Hub + REST APIs):
|
|
|
|
**In `Startup.cs` or `Program.cs`:**
|
|
|
|
```csharp
|
|
public void ConfigureServices(IServiceCollection services)
|
|
{
|
|
// Add CORS policy - MUST be before other services
|
|
services.AddCors(options =>
|
|
{
|
|
options.AddPolicy("AllowQLineWeb", builder =>
|
|
{
|
|
builder
|
|
.WithOrigins(
|
|
"http://localhost:*", // Development
|
|
"http://10.71.50.53:*", // Device IP
|
|
"https://qline.hmg.com", // Production
|
|
"https://your-web-domain.com" // Your web domain
|
|
)
|
|
.AllowAnyHeader()
|
|
.AllowAnyMethod()
|
|
.AllowCredentials() // Required for SignalR
|
|
.SetIsOriginAllowedToAllowWildcardSubdomains();
|
|
});
|
|
});
|
|
|
|
// Add SignalR
|
|
services.AddSignalR();
|
|
|
|
// Add MVC/API Controllers
|
|
services.AddControllers();
|
|
}
|
|
|
|
public void Configure(IApplicationBuilder app)
|
|
{
|
|
// CRITICAL: Enable CORS BEFORE routing and endpoints
|
|
app.UseCors("AllowQLineWeb");
|
|
|
|
// Other middleware...
|
|
app.UseRouting();
|
|
app.UseAuthorization();
|
|
|
|
app.UseEndpoints(endpoints =>
|
|
{
|
|
// Apply CORS to SignalR hub
|
|
endpoints.MapHub<PatientCallingHub>("/PatientCallingHub")
|
|
.RequireCors("AllowQLineWeb");
|
|
|
|
// Apply CORS to API controllers (applies to ALL API routes)
|
|
endpoints.MapControllers()
|
|
.RequireCors("AllowQLineWeb");
|
|
});
|
|
}
|
|
```
|
|
|
|
**Alternative for Controllers (if endpoints not working):**
|
|
|
|
Add `[EnableCors("AllowQLineWeb")]` to your controllers:
|
|
|
|
```csharp
|
|
[ApiController]
|
|
[Route("api/[controller]")]
|
|
[EnableCors("AllowQLineWeb")] // Add this to EACH controller
|
|
public class PatientCallController : ControllerBase
|
|
{
|
|
// Your actions here...
|
|
}
|
|
```
|
|
|
|
#### For IIS:
|
|
|
|
Add to `web.config`:
|
|
|
|
```xml
|
|
<system.webServer>
|
|
<httpProtocol>
|
|
<customHeaders>
|
|
<add name="Access-Control-Allow-Origin" value="*" />
|
|
<add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
|
|
<add name="Access-Control-Allow-Headers" value="Content-Type, Authorization" />
|
|
<add name="Access-Control-Allow-Credentials" value="true" />
|
|
</customHeaders>
|
|
</httpProtocol>
|
|
</system.webServer>
|
|
```
|
|
|
|
---
|
|
|
|
### **Solution 2: Run Web App from Same Domain**
|
|
|
|
Deploy the web app to the same domain as the API:
|
|
- API: `https://ms.hmg.com/nscapi`
|
|
- Web App: `https://ms.hmg.com/qline-web` ✅ (Same origin, no CORS issue)
|
|
|
|
---
|
|
|
|
### **Solution 3: Use Reverse Proxy (Development)**
|
|
|
|
For local development, use a reverse proxy to avoid CORS:
|
|
|
|
#### Using Flutter web with proxy:
|
|
|
|
1. Create `proxy_server.js`:
|
|
```javascript
|
|
const express = require('express');
|
|
const { createProxyMiddleware } = require('http-proxy-middleware');
|
|
|
|
const app = express();
|
|
|
|
app.use('/nscapi', createProxyMiddleware({
|
|
target: 'https://ms.hmg.com',
|
|
changeOrigin: true,
|
|
ws: true, // Proxy websockets for SignalR
|
|
}));
|
|
|
|
app.listen(3000, () => {
|
|
console.log('Proxy running on http://localhost:3000');
|
|
});
|
|
```
|
|
|
|
2. Update `ApiConstants` to use proxy:
|
|
```dart
|
|
static String baseUrl = kIsWeb ? 'http://localhost:3000/nscapi' : 'https://ms.hmg.com/nscapi';
|
|
```
|
|
|
|
---
|
|
|
|
### **Solution 4: Browser Extension (Development Only)**
|
|
|
|
For testing, use a CORS browser extension:
|
|
- Chrome: "CORS Unblock" or "Allow CORS"
|
|
- Firefox: "CORS Everywhere"
|
|
|
|
⚠️ **Warning**: Only for development! Don't use in production.
|
|
|
|
---
|
|
|
|
## Quick Test
|
|
|
|
To verify CORS is the issue, open browser console and run:
|
|
|
|
### Test SignalR Hub:
|
|
```javascript
|
|
fetch('https://ms.hmg.com/nscapi/PatientCallingHub/negotiate?IPAddress=10.71.50.53')
|
|
.then(r => console.log('✅ SignalR CORS working!', r))
|
|
.catch(e => console.error('❌ SignalR CORS blocked:', e));
|
|
```
|
|
|
|
### Test Configuration API:
|
|
```javascript
|
|
fetch('https://ms.hmg.com/nscapi/api/PatientCall/Common_Config_GetByIP', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ ipAddress: '10.71.50.53', apiKey: 'EE17D21C7943485D9780223CCE55DCE5' })
|
|
})
|
|
.then(r => console.log('✅ Config API CORS working!', r))
|
|
.catch(e => console.error('❌ Config API CORS blocked:', e));
|
|
```
|
|
|
|
### Test Weather API:
|
|
```javascript
|
|
fetch('https://ms.hmg.com/nscapi/api/PatientCall/WeatherForecast_GetBy5Days', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ cityID: '297030' })
|
|
})
|
|
.then(r => console.log('✅ Weather API CORS working!', r))
|
|
.catch(e => console.error('❌ Weather API CORS blocked:', e));
|
|
```
|
|
|
|
If you see "CORS blocked" errors, the server needs CORS configuration.
|
|
|
|
---
|
|
|
|
## Current Status
|
|
|
|
- ✅ IP persistence: FIXED (localStorage working)
|
|
- ✅ IP retrieval on reload: FIXED
|
|
- ❌ SignalR connection on web: **BLOCKED BY CORS**
|
|
- ❌ REST API calls on web: **BLOCKED BY CORS**
|
|
- ❌ Configuration API on web: **BLOCKED BY CORS**
|
|
- ✅ All functionality on mobile: Working fine
|
|
|
|
**IMPORTANT:** The web app requires CORS for:
|
|
1. SignalR Hub (`/PatientCallingHub`)
|
|
2. Configuration API (`/api/PatientCall/Common_Config_GetByIP`)
|
|
3. Weather API (`/api/PatientCall/WeatherForecast_GetBy5Days`)
|
|
4. Prayer API (`/api/PatientCall/PrayerTime_Today`)
|
|
5. RSS Feed API (`/api/PatientCall/RssFeed_Get`)
|
|
6. Ticket APIs (`/api/Common/*`, `/api/Gen/*`)
|
|
|
|
**All APIs must have CORS enabled for web deployment.**
|
|
|
|
---
|
|
|
|
## Next Steps
|
|
|
|
1. **Contact backend/server admin** to add CORS headers for web app
|
|
2. **Provide them the allowed origins**:
|
|
- Development: `http://localhost:*`
|
|
- Production: Your web app's domain
|
|
- Device IPs: `http://10.71.50.53:*` (if needed)
|
|
3. **Test after server configuration** is updated
|
|
|
|
---
|
|
|
|
## Technical Details
|
|
|
|
**Why Mobile Works:**
|
|
- Native apps use platform HTTP clients (URLSession, HttpURLConnection)
|
|
- No browser, no CORS enforcement
|
|
|
|
**Why Web Fails:**
|
|
- Web browsers enforce Same-Origin Policy
|
|
- Requires server to send `Access-Control-Allow-Origin` header
|
|
- SignalR needs `Access-Control-Allow-Credentials: true`
|
|
|
|
**What the browser is blocking:**
|
|
```
|
|
Request: http://localhost:xxxxx → https://ms.hmg.com/nscapi
|
|
Response missing: Access-Control-Allow-Origin: http://localhost:xxxxx
|
|
Result: ❌ BLOCKED
|
|
```
|
|
|
|
---
|
|
|
|
**Date:** August 2, 2026
|
|
**Status:** ⚠️ SERVER CONFIGURATION REQUIRED
|
|
|
|
|
|
|
|
|
|
|