I’m running into a CORS issue I just can’t solve.
Setup:
- Backend: Flask app (with Flask-CORS)
- Hosted: on Render.com
- Static files: Served via Flask (
send_from_directory
) - Public frontend: solixa.ai
- Static files domain: custom-va-template.onrender.com
- I do not have my own Cloudflare account; all proxy/CDN is managed by Render.
What works
- All JS and CSS files (e.g.
/main.js
,/styles.css
) are loaded cross-origin without CORS errors.- I see no CORS error for JS/CSS, and in the network tab I see those requests (from
https://solixa.ai
tohttps://custom-va-template.onrender.com
) get 200 OK.
- I see no CORS error for JS/CSS, and in the network tab I see those requests (from
- Only the main HTML file (
/index.html
) gives a CORS error in the browser.
What fails
- Whenever my frontend tries to fetch
/index.html
cross-origin (via fetch, or in devtools), I get:
Access to fetch at 'https://custom-va-template.onrender.com/index.html?v=TIMESTAMP' from origin 'https://solixa.ai' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
- Curl test:
curl -i -H "Origin: https://solixa.ai" "https://custom-va-template.onrender.com/index.html"
…shows no Access-Control-Allow-Origin
header for HTML.
(But curl to /main.js
or /styles.css
DOES show the header.)
My Flask config
from flask import Flask, send_from_directory, request, make_response
from flask_cors import CORS
import os
app = Flask(__name__)
ALLOWED_ORIGINS = [
"https://solixa.ai",
"https://custom-va-template.onrender.com",
"http://localhost:8080",
]
CORS(
app,
resources={r"/*": {"origins": "*"}},
supports_credentials=False,
send_wildcard=True,
always_send=True,
automatic_options=True,
)
UI_ASSETS_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', 'frontend')
@app.route('/', methods=['GET', 'HEAD', 'OPTIONS'])
def serve_chatbot_index_html():
# ... see code above for full details ...
return send_from_directory(UI_ASSETS_DIR, 'index.html')
I also tried explicit CORS headers, after_request hooks, etc. Nothing works for HTML – but JS/CSS always works.
What I tried
- Various Flask-CORS configs, always with
origins
set, also wildcards. - Explicit
@app.after_request
adding ACAO headers, settingCache-Control: no-store
for HTML. - Purging Cloudflare cache, clearing Render cache, redeploys, versioned query strings (cache busters).
- All CDN headers (
Vary
,Origin
, etc) double checked. - No effect: HTML never gets ACAO in response.
Questions
- Why would Render/Cloudflare serve CORS headers for JS/CSS but NOT for HTML, even with identical Flask/CORS config?
- Can Cloudflare or Render be stripping or altering the headers just for HTML content types?
- How can I ensure my HTML (index.html) always gets the right
Access-Control-Allow-Origin
header cross-origin, as my JS/CSS already do? - What else can I try on the Flask or Render side? Is this a known Render+Cloudflare issue?
Any help is very appreciated!