从JS页面请求Flask服务器遭CORS拦截,无需配置CORS如何解决?
问题背景
我正尝试从运行在127.0.0.1:80的JavaScript页面,向运行在127.0.0.1:5000的Python Flask服务器发送GET请求。
Flask服务器代码
import classifyGrade from flask import Flask from flask import request from flask import Response from flask import jsonify import json app = Flask(__name__) @app.route('/') def classify(): ... function ... return response if __name__ == '__main__': app.run(host='0.0.0.0',port=5000,debug=False)
JavaScript代码
function getClassification() { const modulesArray = [ document.getElementById('module_1').value, document.getElementById('module_2').value, document.getElementById('module_3').value, document.getElementById('module_4').value, document.getElementById('module_5').value ] const marksArray = [ document.getElementById('mark_1').value, document.getElementById('mark_2').value, document.getElementById('mark_3').value, document.getElementById('mark_4').value, document.getElementById('mark_5').value ] let module_1 = document.getElementById('module_1').value let module_2 = document.getElementById('module_2').value let module_3 = document.getElementById('module_3').value let module_4 = document.getElementById('module_4').value let module_5 = document.getElementById('module_5').value let mark_1 = document.getElementById('mark_1').value let mark_2 = document.getElementById('mark_2').value let mark_3 = document.getElementById('mark_3').value let mark_4 = document.getElementById('mark_4').value let mark_5 = document.getElementById('mark_5').value let xhttp = new XMLHttpRequest(); xhttp.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { var j = JSON.parse(this.response); } }; /* xhttp.open("GET",classifyModulesURL+"?module_1=" + module_1 + "&mark_1=" + mark_1 + "&module_2=" + module_2 + "&mark_2=" + mark_2 + "&module_3=" + module_3 + "&mark_3=" + mark_3 + "&module_4=" + module_4 + "&mark_4=" + mark_4 + "&module_5=" + module_5 + "&mark_5=" + mark_5); console.log("Request Sent: " + "GET" + classifyModulesURL + "?module_1=" + module_1 + "&mark_1=" + mark_1 + "&module_2=" + module_2 + "&mark_2=" + mark_2 + "&module_3=" + module_3 + "&mark_3=" + mark_3 + "&module_4=" + module_4 + "&mark_4=" + mark_4 + "&module_5=" + module_5 + "&mark_5=" + mark_5); */ xhttp.open("GET",classifyModulesURL+"?modules="+modulesArray+"&marks="+marksArray); xhttp.send(); //POST Attempt //xhttp.open("POST",classifyModulesURL); //xhttp.setRequestHeader("Content-Type", "application/json;charset=UTF-8"); //data = JSON.stringify({"modules": modulesArray, "marks": marksArray}; //xhttp.send(data); return; }
遇到的错误
Access to XMLHttpRequest at 'http://127.0.0.1:5000/?modules=CSC3021,CSC4302,CSC3299,CSC5678,CSC7623&marks=45,66,43,54,78' from origin 'http://127.0.0.1' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
已尝试的方案:
- 修改Flask服务器的端口
- 导入
flask_cors并尝试配置CORS
需求:尽可能不在Flask服务器上配置CORS,只想简单获取GET请求的响应,想问这是浏览器的问题吗?
问题解答
这不是浏览器的“问题”,而是浏览器内置的安全机制。浏览器为了防止跨域请求带来的安全风险(比如恶意网站窃取用户数据),会严格执行同源策略——只有当请求的协议、域名、端口三者完全一致时,才允许正常发送AJAX请求。你的前端在127.0.0.1:80,后端在127.0.0.1:5000,端口不同,属于跨域,所以浏览器会拦截请求,除非后端返回Access-Control-Allow-Origin这类CORS响应头。
Postman能正常请求是因为它是API调试工具,不执行浏览器的同源策略限制,所以不受CORS约束。
如果不想在Flask后端配置CORS,有几个替代方案:
- 同源部署:把前端HTML文件放在Flask项目的
static文件夹里,用Flask直接托管静态资源,这样前端和后端同源,就不会触发跨域限制。 - 调试用跨域插件:Chrome上有类似“Allow CORS: Access-Control-Allow-Origin”的插件,开启后能临时绕过CORS限制,但仅适合开发调试,不能用于生产环境。
- 反向代理:用Nginx等工具把前端和后端的请求代理到同一域名下,比如访问
127.0.0.1:80/api时,Nginx转发到127.0.0.1:5000,前端请求/api就不会跨域了。
内容的提问来源于stack exchange,提问作者Orple43

