一、HTTP 301与302的核心区别
- 301 Moved Permanently(永久重定向)
资源已永久迁移 至新URL,搜索引擎会更新索引并将权重转移到新地址。客户端(如浏览器)后续请求应直接访问新URL。
典型场景:域名更换、网站永久性结构调整。 - 302 Found(临时重定向)
资源临时迁移 至新URL,搜索引擎保留原URL索引。客户端应继续使用原URL发起后续请求。
典型场景:A/B测试、临时维护页跳转、登录后临时跳转。
⚠️ 关键差异:301影响SEO权重传递,302不影响;301被浏览器缓存,302每次需重新验证。
二、浏览器端的请求处理机制
常规页面请求(非Ajax)
- 自动重定向流程
浏览器收到301/302响应后,自动读取Location
头并跳转到新URL,用户感知为URL变化和页面刷新。
graph LR
A[发起请求] --> B{收到301/302}
B --> C[读取Location头]
C --> D[自动跳转至新URL]
Ajax请求(XMLHttpRequest/Fetch)
-
核心限制 :
Ajax请求无法显式拦截301/302响应。浏览器会默认follow,自动跟随重定向,最终返回的是重定向链末端的200响应。
js// 失败尝试:无法捕获中间302响应 axios.get('/api/data').then(res => { // res实际是重定向后页面的200响应 });
-
解决方案:
-
服务端配合:对Ajax请求返回非3xx状态码(如403),并在响应体中包含跳转URL:
js// 前端处理逻辑 fetch('/api/auth', { credentials: 'include' }) .then(res => { if (res.status === 403) { window.location.href = res.data.redirectUrl; // 手动跳转 } });
-
Fetch API手动处理:
jsfetch('/api/login', { redirect: 'manual' }) // 禁止自动重定向 .then(res => { if (res.status === 302) { const newUrl = res.headers.get('Location'); window.location.href = newUrl; // 显式跳转 } });
-
三、Node.js端的请求处理机制
1、Node作为服务端实现
重定向
-
原生HTTP模块:通过设置响应头实现:
jsconst http = require('http'); http.createServer((req, res) => { // 301重定向 res.writeHead(301, { 'Location': 'https://newdomain.com' }); res.end(); }).listen(3000);
-
Express框架:使用语法糖简化操作:
jsconst express = require('express'); const app = express(); app.get('/old', (req, res) => { res.redirect(301, '/new'); // 永久重定向 });
2、Node作为客户端处理
重定向
- 禁止自动跟随:通过配置拦截中间响应:
如果是Axios,设置maxRedirects为0,来阻止跳转

js
// Axios示例--如果POST请求需要catch err获取headrs里的location
axios.get('http://example.com', {
maxRedirects: 0, // 禁用自动重定向
validateStatus: status => status < 400 // 允许3xx状态码
}).then(res => {
if (res.status === 302) {
console.log('重定向目标:', res.headers.location);
}
});
- 递归跟踪重定向链(如爬虫场景):
js
async function traceRedirects(url, maxDepth = 5) {
const res = await axios.get(url, { maxRedirects: 0 });
if ([301, 302].includes(res.status)) {
return traceRedirects(res.headers.location, maxDepth - 1);
}
return res.data;
}
四、最佳实践与常见问题
-
安全性强化
- 浏览器端:对敏感操作(如支付)避免使用302,防止重定向劫持
- Node.js端:校验
Location
头域名,防止开放重定向漏洞
-
SEO优化建议
- 网站迁移时必用301,确保搜索引擎权重转移
- 避免302链过长(如>3次),可能被搜索引擎判为作弊
-
Ajax兼容性方案
方案 优点 缺点 返回自定义状态码(如403) 前端完全可控 需改造服务端逻辑 Fetch手动跳转 符合标准 旧浏览器不支持
💡 调试技巧:
- 浏览器开发者工具中勾选 "Preserve log" 查看重定向链
- Node.js端用
axios.interceptors
打印中间请求信息
结语
理解301/302在浏览器与Node.js环境的差异,关键在于把握重定向的透明性边界:浏览器隐藏跳转细节以保证用户体验,而Node.js作为中间层需显式处理。在前后端分离架构下,建议采用"服务端返回指令 + 前端控制跳转"的混合模式,兼顾安全性与灵活性。