Flutter Web请求Flask接口报No 'Access-Control-Allow-Origin'跨域错误求解
问题根因
这是跨域资源共享(CORS)预检请求处理不当导致的报错,前后端代码都存在需要修正的点:
- 前端错误配置了CORS响应头到请求头中,触发了非简单请求的预检逻辑
- 后端Flask接口没有处理OPTIONS类型的预检请求,且异常返回场景未携带CORS头
修复步骤
1. 修正Flutter前端代码
Access-Control-Allow-Origin属于服务端返回的响应头,前端请求不需要携带该字段,删除多余头即可:
child: ElevatedButton( child: const Text('Download'), onPressed: () async { // 删除多余的Access-Control-Allow-Origin请求头 var header = { "Accept": "application/json" }; var url = Uri.parse( 'http://192.168.2.237:8080/youtube?url=www.google.com'); print('URL is : ${url}'); var response = await http.get(url, headers: header); print('Response status: ${response.statusCode}'); print('Response body: ${response.body}'); }, ),
2. 修正Flask后端代码
推荐使用flask-cors扩展统一处理CORS逻辑,避免手动配置遗漏:
- 首先安装扩展:
pip install flask-cors - 修正后的接口代码:
from flask import Flask, request, json from flask_cors import CORS app = Flask(__name__) # 全局配置CORS,自动处理OPTIONS预检请求 CORS(app, supports_credentials=True) @app.route("/youtube") def firstGetAPI(): try: url = request.args.get('url') print(f'URL is {url}') res = "Success" return res, 200 except Exception as e: response = {"status":"Fail", "message":str(e)} return json.dumps(response), 200, {"Content-Type": "application/json"} if __name__ == "__main__": app.run(host='0.0.0.0', debug=True, port=8080)
如果不想使用第三方扩展,可手动添加OPTIONS请求处理逻辑,同时给异常返回也加上CORS头:
from flask import Flask, request, json, Response app = Flask(__name__) # 路由同时支持GET和OPTIONS请求 @app.route("/youtube", methods=['GET', 'OPTIONS']) def firstGetAPI(): # 处理预检请求 if request.method == 'OPTIONS': response = Response() response.headers.set('Access-Control-Allow-Origin', '*') response.headers.set('Access-Control-Allow-Headers', 'Content-Type,Authorization') response.headers.set('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS') return response, 200 try: url = request.args.get('url') print(f'URL is {url}') res = "Success" response = Response(res) response.headers.set('Access-Control-Allow-Origin', '*') return response, 200 except Exception as e: response = {"status":"Fail", "message":str(e)} resp = Response(json.dumps(response), content_type='application/json') resp.headers.set('Access-Control-Allow-Origin', '*') return resp, 200 if __name__ == "__main__": app.run(host='0.0.0.0', debug=True, port=8080)
内容的提问来源于stack exchange,提问作者Siddhpura Amit
相关产品推荐
相关产品推荐

