Flask桥接前后端传递经纬度时遭遇CORS跨域错误求助
Flask前后端数据传递遭遇CORS错误排查与解决
我用Flask做前后端桥接,将前端获取的纬度(latitude)、经度(longitude)传递至Python脚本,但提交数据时始终遇到以下CORS错误:
Access to XMLHttpRequest at 'http://localhost:5000/weather-producer.py' from origin 'null' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. script.js:15 POST http://localhost:5000/weather-producer.py net::ERR_FAILED 403 (Forbidden)
Python代码
from flask import Flask, request import logging from os.path import dirname, abspath from time import gmtime import http.client from flask_cors import CORS from confluent_kafka import Producer logger = logging.getLogger('') # Root logger, to catch all submodule logs logger.setLevel(logging.DEBUG) formatter = logging.Formatter('%(asctime)s.%(msecs)03d|%(levelname)s|%(filename)s| %(message)s', datefmt='%Y-%m-%d %H:%M:%S') formatter.converter = gmtime # Log UTC time if len(logger.handlers) == 0: console = logging.StreamHandler() console.setFormatter(formatter) logger.addHandler(console) def _full_path_of(path): base_dir = dirname(dirname(dirname(abspath(__file__)))) return f'{base_dir}{path}' def delivery_callback(error, msg) -> None: """ Per-message delivery callback (triggered by poll() or flush()) :param error: None if the message was successfully delivered :param msg: Message metadata :return: None """ if error is not None: logger.error(f'Failed to deliver message: {error}') else: logger.info(f'Produced record to topic {msg.topic()} partition [{msg.partition()}] @ offset {msg.offset()}') def get_weather_data(latitude, longitude): conn = http.client.HTTPSConnection("weatherapi-com.p.rapidapi.com") headers = { 'X-RapidAPI-Key': "randomAPIkey", 'X-RapidAPI-Host': "weatherapi-com.p.rapidapi.com" } query = f"/current.json?q={latitude},{longitude}" conn.request("GET", query, headers=headers) res = conn.getresponse() data = res.read() return data.decode("utf-8") app = Flask(__name__) CORS(app, resources={r"/weather-producer.py": {"origins": "*"}}) @app.route("/weather-producer.py", methods=['POST']) def weather_producer(): latitude = request.form.get('textbox1') longitude = request.form.get('textbox2') topic = 'axual-local-example-weathertopic' configuration = { 'bootstrap.servers': 'platform.local:31757', 'security.protocol': 'SSL', 'ssl.endpoint.identification.algorithm': 'none', 'ssl.certificate.location': _full_path_of('/resources/client-cert/standalone/client.pem'), 'ssl.key.location': _full_path_of('/resources/client-cert/standalone/clientkey.pem'), 'ssl.ca.location': _full_path_of('/resources/client-cert/standalone/client.pem'), 'acks': 'all', 'logger': logger } producer = Producer(configuration) try: logger.info(f'Starting kafka producer to produce to topic: {topic}. ^C to exit.') for n in range(10): record_key = f'key_{n}' record_value = get_weather_data(latitude, longitude) producer.poll(0) producer.produce(topic, key=record_key, value=record_value, on_delivery=delivery_callback) logger.info('Done producing.') except KeyboardInterrupt: logger.info('Caught KeyboardInterrupt, stopping.') finally: if producer is not None: logger.info('Flushing producer.') producer.flush() return 'Success', 200 if __name__ == "__main__": app.run(port=5000, debug=True)
JavaScript代码
function submitForm(event) { event.preventDefault(); // Prevent form submission var textbox1Value = document.getElementById("textbox1").value; var textbox2Value = document.getElementById("textbox2").value; var xhttp = new XMLHttpRequest(); xhttp.open("POST", "http://localhost:5000/weather-producer.py", true); xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); xhttp.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { console.log(this.responseText); } }; xhttp.send("textbox1=" + textbox1Value + "&textbox2=" + textbox2Value); }
问题排查与修复步骤
- 修正CORS路径匹配或改为全局允许:当前配置的
resources={r"/weather-producer.py": {"origins": "*"}}可能存在路径匹配偏差,建议先改为全局允许进行测试(生产环境需限制指定origin):
若需精确匹配,确保路由路径与配置完全一致,可保留原配置但确认Flask路由无额外重写规则。# 替换原CORS配置为全局允许 CORS(app) - 处理origin为null的场景:前端直接打开本地HTML文件时,请求origin会是
null,部分CORS配置对该origin支持不佳。解决方式二选一:- 将前端页面部署到HTTP服务器(如执行
python -m http.server 8000,访问http://localhost:8000/xxx.html),让请求拥有正常origin; - 修改CORS配置显式允许
nullorigin:CORS(app, resources={r"/weather-producer.py": {"origins": ["*", "null"]}})
- 将前端页面部署到HTTP服务器(如执行
- 确认Flask-CORS加载顺序与版本:确保
CORS(app)在app = Flask(__name__)之后、路由定义之前调用,同时确认已安装最新版flask-cors(执行pip install --upgrade flask-cors)。 - 覆盖OPTIONS预检查请求:CORS预检查会发送OPTIONS请求,需确保配置覆盖该方法:
CORS(app, resources={r"/weather-producer.py": { "origins": "*", "methods": ["POST", "OPTIONS"] }})
内容的提问来源于stack exchange,提问作者Gion
相关产品推荐
相关产品推荐

