什么是重定向?重定向与请求转发的区别?

重定向是服务器返回 3xx 让浏览器重新访问新 URL(地址栏会改变,需二次请求),而请求转发只在同一服务器内部把同一 request 转给其他资源处理(一次请求,地址栏不变)。

一、重定向(Redirect)—— 客户端跳转

工作流程

  1. 请求阶段

    • 客户端访问 URL-A(如 /login

  2. 服务端响应

    • 返回 3xx 状态码(如 302)和 Location 头(如 /dashboard

  3. 客户端行为

    • 自动向新 URL(/dashboard)发起第二次请求

  4. 最终结果

    • 浏览器地址栏 显示新 URL

核心特点
维度说明
执行层级客户端主导跳转(浏览器自动发起新请求)
HTTP状态码3xx(如 301 永久重定向、302 临时重定向、307 临时重定向保留方法)
地址栏变化✅ 显示新 URL
请求次数≥ 2 次(每次跳转需完整请求)
数据传递❌ 原始请求参数丢失(除非手动拼接到新URL)
性能开销较高(多次网络往返)
典型场景
  • 用户登录后跳转到首页

  • 网站改版后旧链接指向新地址

  • 支付完成跳转回商户页面

二、请求转发(Forward)—— 服务端跳转

工作流程

  1. 请求阶段

    • 客户端访问 URL-A(如 /process

  2. 服务端内部

    • 服务端组件(如 Servlet)将请求转发给另一组件(如 JSP)

    • 返回响应给客户端

  3. 最终响应

    • 最终处理组件生成响应,直接返回给客户端

    • 浏览器地址栏 仍显示原始 URL

核心特点
维度说明
执行层级服务端内部跳转(客户端无感知)
HTTP状态码200(客户端只收到一次响应)
地址栏变化❌ 保持原始 URL
请求次数1 次
数据传递✅ 共享同一个 request 对象(可传递参数)
性能开销低(无额外网络请求)
典型场景
  • MVC 架构中 Controller 调用 View 渲染页面

  • 权限验证失败跳转到错误页(保持原始URL)

  • 多步骤表单处理(各步骤共享表单数据)

三、核心区别对比表

特性重定向(Redirect)请求转发(Forward)
跳转控制方客户端(浏览器)服务端(如 Servlet/JSP)
地址栏变化✅ 显示新 URL❌ 保持原 URL
HTTP 请求次数≥ 2 次1 次
数据共享❌ 需手动传参(URL参数/cookies)✅ 通过 request.setAttribute() 传递
性能较差(多次网络往返)较好(服务端内部调度)
目标资源范围可跳转任意 URL(包括外部域名)仅限当前应用内部资源
实现代码示例response.sendRedirect("/new-path")request.getRequestDispatcher().forward()

四、关键注意事项

1. 重定向陷阱
  • 循环重定向: A → B → A → B...(浏览器报错 ERR_TOO_MANY_REDIRECTS

  • 解决方案

    • 检查重定向逻辑终止条件

    • 用 301 代替 302 避免浏览器重复判断

2. 转发限制
  • 响应已提交: 若已调用 response.getWriter() 则不能再转发(抛出 IllegalStateException

  • 解决方案: 在转发前避免输出响应内容

3. 跨域问题
方式跨域支持
重定向✅ 可跳转外部域名
请求转发❌ 仅限同应用内部

五、如何选择?

  • 用重定向 When

    • 需要地址栏更新(如登录后跳转)

    • 跳转到外部网站

    • 避免表单重复提交(PRG模式:Post/Redirect/Get)

  • 用请求转发 When

    • 保持地址栏不变(如错误页面)

    • 需要传递复杂对象(如数据库查询结果)

    • 提升性能(避免额外网络请求)

📌 黄金法则需更新地址栏 → 重定向 需隐藏实现细节 → 请求转发

六、代码示例

1. 重定向(Java Servlet)
// 丢失原始请求参数
response.sendRedirect("/new-page"); 
​
// 保留参数(手动拼接)
String param = "?user=" + URLEncoder.encode(userName, "UTF-8");
response.sendRedirect("/dashboard" + param);
2. 请求转发(Java Servlet)
// 传递数据
request.setAttribute("data", queryResult);
​
// 转发到JSP
RequestDispatcher dispatcher = request.getRequestDispatcher("/result.jsp");
dispatcher.forward(request, response); 

总结

机制本质地址栏数据传递性能
重定向客户端跳转(二次请求)变化需手动处理较低
请求转发服务端跳转(内部调度)不变自动共享请求域数据较高

选择策略

  • 需要 SEO 友好的新 URL → 301 重定向

  • 多步骤表单共享数据 → 请求转发

  • 支付后防止刷新重复扣款 → 302/307 重定向

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

tsxchen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值