基于Flask的站点中Chrome不跟随XMLHttpRequest后的重定向问题
解决Flask中XHR POST后重定向不生效的问题
这问题我之前开发Flask项目时也踩过坑!核心原因是XMLHttpRequest(AJAX)请求的特性:浏览器不会自动为异步AJAX请求触发页面级的重定向跳转,得咱们手动在前端脚本里处理才行。
问题根源
当你用e.preventDefault()阻止了表单的默认提交行为,改用XHR发送POST请求后:
- Flask视图返回的3xx重定向响应会被XHR对象接收,而不是浏览器的页面导航系统
- XHR默认只会获取重定向目标页面的内容,不会主动让当前页面跳转到该URL
解决方案
这里分两种处理方式,推荐第一种更可控的方案:
方案1:后端返回JSON指令,前端手动跳转
修改Flask的视图函数,处理完数据后返回包含重定向URL的JSON响应,而不是直接redirect():
from flask import render_template, request, jsonify @app.route('/main/page1', methods=['GET', 'POST']) def page1(): if request.method == 'GET': # 渲染初始页面 return render_template('page1.html') elif request.method == 'POST': # 解析前端传来的JSON数据 post_data = request.get_json() # 这里写你的数据处理逻辑... # 比如验证数据、存入数据库等 # 返回JSON,告诉前端要跳转的地址 return jsonify({"redirect_url": "/your_target_page"})
然后修改前端的XHR代码,监听请求完成事件,拿到跳转指令后手动触发页面跳转:
var form = document.getElementById('process_form'); form.onsubmit = function (e) { e.preventDefault(); // 先确保你正确获取了表单数据,比如: var formData = { // 示例:从表单输入框取值 username: document.getElementById('username').value, content: document.getElementById('content').value }; var xhr = new XMLHttpRequest(); xhr.open('POST', '/main/page1', true); xhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8'); // 监听请求完成事件 xhr.onload = function() { if (xhr.status === 200) { var response = JSON.parse(xhr.responseText); if (response.redirect_url) { // 手动跳转到目标页面 window.location.href = response.redirect_url; } } }; xhr.send(JSON.stringify(formData)); };
方案2:后端仍返回重定向,前端解析Location头
如果因为某些原因必须让后端返回redirect(),可以在前端监听XHR的响应,解析Location响应头来跳转:
var form = document.getElementById('process_form'); form.onsubmit = function (e) { e.preventDefault(); var formData = { /* 你的数据 */ }; var xhr = new XMLHttpRequest(); // 禁止XHR自动跟进重定向,才能拿到原始的3xx响应 xhr.open('POST', '/main/page1', true); xhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8'); xhr.followRedirects = false; xhr.onload = function() { if (xhr.status >= 300 && xhr.status < 400) { var redirectUrl = xhr.getResponseHeader('Location'); if (redirectUrl) { window.location.href = redirectUrl; } } }; xhr.send(JSON.stringify(formData)); };
这种方案需要注意:不同浏览器对followRedirects的支持可能有差异,不如方案1稳定。
补充说明
如果你不需要用AJAX提交,其实可以直接去掉e.preventDefault(),让表单以默认方式提交,这样浏览器会自动跟随Flask的重定向。但既然你选择了AJAX,肯定是需要在提交过程中做一些异步处理(比如加载动画、数据验证),所以还是推荐方案1的方式。
内容的提问来源于stack exchange,提问作者YANPENG YIN
相关产品推荐
相关产品推荐

