在网上搜了一下并没有什么好的解决方案,有的话也只是告诉你如何修改代码,并没有讲明白其中的原理以及导致问题的核心,因此特意去了解了一下HTTP的规范找到了答案
- 问题说明
问题出现的流程大致都是前端发送Ajax请求给后端,进行一些查库校验等,这时根据逻辑进行重定向跳转到不同的页面,检查控制台可以显示,确实进行了路由的跳转,且跳转对象的函数内也可以执行相应的代码
可以发现DEBUG打印了302进行了重定向,且也进行了重定向后的路由跳转,但此时去看前端会发现并没有进行路由跳转
问题就出在请求方式这里,我的前端是通过AJAX的POST请求去发的,当我直接在浏览器进行输入路由进行测试时候可以发现重定向成功了(记得先让你的路由先支持GET方式),此时可能导致我误解是POST的原因,搜了相关资料确实说了POST会造成相关原因,但最后解决的核心点在AJAX
- HTTP规范分析
HTTP/1.1规范规定,对于POST请求的重定向,浏览器的默认行为是不会自动地进行跳转的。这是为了防止用户无意中重复提交表单数据,因为POST请求通常用于提交表单。
在HTTP/1.1规范中,当服务器返回3xx状态码(重定向状态码)时,浏览器应该按照响应头中的Location字段的值进行重定向。然而,在实际应用中,对于POST请求,浏览器通常会将重定向的处理方式留给开发者来决定,而不会自动地执行。
对于GET请求,浏览器通常会遵循规范,自动进行重定向。但由于POST请求包含请求体(Request Body),而GET请求则不包含,因此在POST请求中,浏览器会要求开发者来处理重定向,以确保用户的数据安全。
所以,在处理POST请求的重定向时,开发者需要通过编写前端代码,通过JavaScript等手段来检测重定向,并根据需要手动执行跳转。
- AJAX分析
使用 Ajax 进行异步请求时,浏览器并不会自动处理服务器端的重定向,因为 Ajax 请求通常用于在不刷新整个页面的情况下获取数据。由于这一点,即使服务器返回了重定向响应,浏览器也会在背后接收重定向,但不会自动更新页面。
所以,如果你希望在 Ajax 请求中进行重定向,你需要在前端代码中手动处理。可以通过在成功回调中手动设置 window.location.href
实现
如果你直接使用 <a>
标签或者表单提交的方式,浏览器会自动处理重定向,但使用 Ajax 时需要手动处理。这是因为 Ajax 的设计初衷是异步获取数据,而不是进行完整的页面导航
- 总结
解决方案就是要么别用AJAX直接用a
标签去做这个事儿,我这里要用Layui的表单去做校验,所以就得到JS层去做这个事。要么用AJAX的话就在前端进行重定向,后端这种前后端不分离的模板开发的方式都不会生效的,因为AJAX不会给你处理的,按照FLASK的处理方式,也是会将这个重定向的结果返回,也就是那个页面,但是因为是AJAX接收的,所以返回的结果会传递到回调函数中,这里你可以去打印一下AJAX的回调,可以发现返回了一个HTML页面的全部代码,也就是FLASK重定向后返回的东西。因此最后我是直接在前端进行重定向,跳转到目标页面,在目标页面渲染前做逻辑处理
- 直接进行重定向后端
layui.use(function () {
let form = layui.form;
form.on('submit(search)', function (data) {
let field = data.field;
window.location.href = '{{ url_for('web.identify')}}' + `?code=${field.code}`;
return false;
});
})
- 后端路由去处理返回的数据以及HTML
@bp.route('/identify')
def identify():
code = request.args.get('code')
products = SecurityCode.query.filter_by(security_code=code).first()
products_json = {
'goods_name': products.goods_name,
'security_code': products.security_code,
'queries_num': products.queries_num
} if products else None
return render_template('identify.html', **locals())
自己根据情况合理调整即可,还是得多了解HTTP和AJAX的规则- -