点击HTML按钮调用Python脚本遇CORS错误,求解决方案
问题分析与解决方案
CORS错误原因
你遇到的CORS错误核心原因有两个:
- 跨源协议不一致:直接打开本地HTML文件时,浏览器使用
file://协议,而Python服务运行在http://localhost:5000(HTTP协议),两者协议不同,触发浏览器同源策略拦截。 - CGI脚本的局限性:你的Python代码用
cgi模块处理请求,这种方式依赖Apache/Nginx等Web服务器解析,且无法自动添加CORS响应头,没法解决跨源问题。
可行方案:用Flask搭建后端服务
下面是一套完整可运行的方案,基于Flask框架实现前后端交互,支持参数传递并解决CORS问题。
步骤1:安装依赖
首先安装所需Python包:
pip install flask flask-cors requests
步骤2:后端Python代码(app.py)
用Flask搭建API接口,处理前端请求、调用ServiceNow API并返回结果:
from flask import Flask, request, jsonify from flask_cors import CORS import requests import json import base64 app = Flask(__name__) # 开发环境允许所有跨源请求,生产环境请替换为具体域名 CORS(app) # 替换为你的ServiceNow账号密码,格式:用户名:密码,然后Base64编码 SN_AUTH = base64.b64encode(b"your_username:your_password").decode() @app.route('/api/call-snow', methods=['POST']) def call_snow_api(): # 获取前端传递的JSON参数 req_data = request.get_json() var1 = req_data.get('var1', 'default_value1') var2 = req_data.get('var2', 'default_value2') # 调用ServiceNow的Incident API sn_url = "https://instance.service-now.com/api/now/table/incident" payload = json.dumps({ "short_description": f"Button click test: var1={var1}, var2={var2}" }) headers = { 'Authorization': f'Basic {SN_AUTH}', 'Content-Type': 'application/json' } try: response = requests.post(sn_url, headers=headers, data=payload) response.raise_for_status() # 抛出HTTP错误 return jsonify({ "status": "success", "snow_response": response.json() }) except requests.exceptions.RequestException as e: return jsonify({ "status": "error", "message": str(e) }), 500 if __name__ == '__main__': app.run(host='localhost', port=5000, debug=True)
步骤3:前端HTML代码
将前端页面放在Flask项目的static文件夹下(没有则新建),通过http://localhost:5000/static/index.html访问,和后端同域彻底避免CORS问题:
<!DOCTYPE html> <html> <head> <title>Call ServiceNow via Python</title> <script src="https://code.jquery.com/jquery-3.6.4.min.js"></script> </head> <body> <button class="button button1" onclick="callPythonScript()">Click Here to open a request</button> <script> function callPythonScript() { alert("Request sent"); $.ajax({ url: "/api/call-snow", // 同域下可省略域名 type: "POST", contentType: "application/json", data: JSON.stringify({ "var1": "your_custom_value1", "var2": "your_custom_value2" }), success: function(response) { console.log("Success:", response); alert("Incident created successfully!"); }, error: function(xhr) { console.log("Error:", xhr.responseText); alert("Failed to create incident"); } }); } </script> </body> </html>
步骤4:运行服务
- 启动Flask后端:
python app.py
- 在浏览器中访问
http://localhost:5000/static/index.html,点击按钮即可触发请求。
关键注意事项
- ServiceNow认证:务必将代码中的
your_username:your_password替换为实际ServiceNow账号密码,再进行Base64编码。 - 生产环境配置:生产环境不要用
CORS(app)允许所有源,应指定允许的前端域名,例如:CORS(app, resources={r"/api/*": {"origins": "https://your-frontend-domain.com"}}) - 避免本地直接打开HTML:必须通过HTTP协议访问前端页面(比如Flask提供的静态文件路径),不要直接双击打开HTML文件(file://协议)。
内容的提问来源于stack exchange,提问作者nooblearner
相关产品推荐
相关产品推荐

