fetch 默认不自动跟随302/301重定向,需显式设置 redirect: "follow" 或手动解析 location 头;推荐后端返回 json 重定向路径,前端用 window.location.href 跳转。

Fetch API 本身不会自动跟随 302 或 301 重定向响应(除非你显式设置 redirect: "follow"),而服务端用 Response.Redirect(如 ASP.NET 的 Response.Redirect("url"))发出的跳转,本质上就是返回一个带 Location 头的 302 响应。所以关键不是“配合”,而是理解 Fetch 如何处理这类响应,以及前端如何正确响应它。
Fetch 默认不自动跳转,需手动解析 Location
当你用 fetch('/login', { method: 'POST' }) 请求后端登录接口,后端调用 Response.Redirect("/dashboard"),浏览器收到的是:
- HTTP 状态码
302 Found - 响应头包含
Location: /dashboard - 响应体通常为空或简单提示
但默认情况下,fetch 会把这次 302 当作普通响应(response.ok === false),不会自动跳转到 /dashboard —— 这和传统表单提交或 window.location 行为不同。
方案一:服务端返回 JSON + 前端手动跳转(推荐)
更可控、更符合前后端分离习惯的做法是:后端不直接重定向,而是返回结构化数据,由前端决定是否跳转。
后端(例如 ASP.NET Web Forms 或 MVC):
// 不用 Response.Redirect
context.Response.StatusCode = 200;
context.Response.ContentType = "application/json";
context.Response.Write("{\"redirect\":\"/dashboard\"}");
前端 fetch 处理:
fetch('/login', { method: 'POST', body: formData })
.then(r => r.json())
.then(data => {
if (data.redirect) {
window.location.href = data.redirect;
} else if (data.error) {
alert(data.error);
}
});
方案二:Fetch 设置 redirect: "manual" 并读取 Location 头
如果你必须保留服务端 Response.Redirect 的逻辑(比如遗留系统),可让 Fetch 不自动跟随重定向,自己提取 Location:
fetch('/login', {
method: 'POST',
redirect: 'manual' // 关键:禁用自动跳转
})
.then(response => {
if (response.type === 'opaqueredirect') {
// 注意:opaque redirect 无法读取 headers(CORS 限制)
throw new Error('Cannot read Location header due to CORS');
}
if (response.redirected && response.headers.has('Location')) {
const url = response.headers.get('Location');
window.location.href = url;
} else if (response.status >= 300 && response.status
<p><font color="red">⚠️ 注意</font>:跨域请求下,<code>redirect: 'manual'</code> 会导致响应类型变为 <code>'opaqueredirect'</code>,此时无法读取 <code>Location</code> 头(CORS 限制)。该方案仅适用于同源请求。</p>
<h3>方案三:用 redirect: "follow" + 检查最终 URL(仅限同源)</h3>
<p>如果只是想确认跳转是否发生,且无需干预过程:</p>
<pre class="brush:php;toolbar:false;">fetch('/login', { method: 'POST', redirect: 'follow' })
.then(response => {
console.log('最终响应 URL:', response.url); // 如 https://site.com/dashboard
// 但注意:此时页面并未跳转,只是 fetch 请求跟到了最终地址
// 若需真实跳转,仍要手动 window.location.assign(response.url)
});
这个方式适合调试,但不能替代页面导航 —— 它只影响 fetch 请求链,不影响当前浏览器地址栏。










