当前位置: 首页 > news >正文

前端请求返回 HTTP Status 0?这个坑 90% 的开发者都会踩!

🔥 前端请求返回 HTTP Status 0?这个坑 90% 的开发者都会踩!

OIP-C2

服务器明明好好的,前端却报错:status 0?问题可能就藏在你忽略的那一行配置里。

💡 问题现象

最近在项目开发中遇到了一个诡异的问题:

  • ✅ 后端 API 完全正常
  • ✅ CORS 配置正确无误
  • ✅ Cookie 中有有效 token
  • ✅ 手动测试都能成功
  • 但前端页面请求就是返回 HTTP Status 0
// 前端控制台报错
API 响应不是有效的 JSON: http://localhost:9421/api/v1/media?page=1&per_page=20, status: 0

🐛 排查过程

第一步:验证后端

直接在浏览器访问 API,成功返回数据!说明后端没问题。

curl http://localhost:9421/api/v1/media/?page=1&per_page=20
# ✅ 返回正常 JSON 数据

第二步:检查 CORS

测试 OPTIONS 预检请求,完美通过

// CORS 头都正确
Access-Control-Allow-Origin: http://localhost:3000
Access-Control-Allow-Credentials: true

第三步:验证认证

Cookie 中有有效的 JWT token,手动发起请求测试:

// ✅ 成功
fetch('http://localhost:9421/api/v1/media/?page=1&per_page=20', {credentials: 'include',headers: {'Authorization': 'Bearer xxx'}
})
// Status: 200 ✓

第四步:排除插件干扰

为了彻底排除浏览器插件(如广告拦截器、代理扩展等)对请求的干扰,我们在无痕模式下禁用了所有插件和脚本,再次发起请求。

// 在无痕模式下,所有扩展默认禁用
fetch('http://localhost:9421/api/v1/media/?page=1&per_page=20', {credentials: 'include'
})
// 结果:仍然返回 status 0

确认问题与插件无关,继续深入调试。

第五步:发现问题

继续深入调试,发现了一个关键信息:

Response {status: 0,type: "opaqueredirect",  // ← 关键!ok: false,headers: {}  // 空的!
}

opaque-redirect 是什么鬼?!

🎯 问题根源

原来,问题出在这行代码上:

// ❌ 错误的配置
const response = await fetch(url, {method: 'GET',credentials: 'include',redirect: 'manual'  // ← 就是这个!
});

什么是 redirect: 'manual'

Fetch API 提供了三种重定向模式:

模式 行为 使用场景
follow(默认) 自动跟随重定向 大多数情况
manual 不跟随重定向,返回 opaque-redirect 需要手动处理重定向 URL
error 遇到重定向直接报错 严格模式

为什么会返回 Status 0?

  1. 前端请求发送后,后端返回 3xx 重定向响应(比如重定向到登录页)
  2. 因为设置了 redirect: 'manual',浏览器不会跟随重定向
  3. 浏览器返回一个 opaque-redirect 类型的响应
  4. 这个响应的 status = 0headers = {},body 为空
  5. 尝试解析 JSON 时就会报错:"Unexpected end of input"

为什么会有 redirect: 'manual' 这个选项?

既然这个选项这么容易出问题,那它存在的意义是什么?

根据 Fetch 规范,redirect: 'manual' 的设计初衷主要是为了浏览器内部导航Service Worker 等特定场景。在这些场景下,开发者需要完全控制重定向的处理流程。但对于普通的前端应用代码,你几乎永远不需要用到它

换句话说:除非你在写 Service Worker 或做非常底层的网络控制,否则永远不要碰 redirect: 'manual'

✅ 解决方案

方案 1:移除 redirect: 'manual'(推荐)

// ✅ 正确的做法
const response = await fetch(url, {method: 'GET',credentials: 'include'// 不设置 redirect,使用默认的 'follow'
});

让浏览器自动处理重定向,99% 的情况都应该这样做!

方案 2:如果你确实需要处理重定向(但不用 manual

// 正确的重定向处理方式:在响应中判断状态码
const response = await fetch(url, {method: 'GET',credentials: 'include'
});if (response.redirected) {// 重定向发生了,response.url 已经是最终 URLconsole.log('重定向到了:', response.url);
}if (response.status === 302) {// 也可以手动获取重定向地址(但不推荐手动跳转)const location = response.headers.get('Location');
}

注意:使用默认的 follow 模式,浏览器会自动跟随重定向,你拿到的是最终响应。response.redirected 属性可以告诉你是否发生过重定向。

📝 最佳实践

✅ DO(推荐做法)

// 1. 使用默认配置
fetch('/api/data', {method: 'GET',credentials: 'include'
});// 2. 如果需要处理认证失败,在响应中判断
fetch('/api/data', {credentials: 'include'
})
.then(response => {if (response.status === 401) {// 未认证,跳转到登录页window.location.href = '/login';}return response.json();
});// 3. 检查是否发生了重定向
const response = await fetch('/api/data');
if (response.redirected) {console.log('请求被重定向到了:', response.url);
}

❌ DON'T(避免这样做)

// 1. 不要随意设置 redirect: 'manual'
fetch('/api/data', {redirect: 'manual'  // ❌ 除非你非常清楚后果
});// 2. 不要这样手动处理重定向(这是错误的示范)
fetch('/api/data', {redirect: 'manual'
}).then(response => {// 这段代码几乎永远不会按预期工作!if (response.type === 'opaqueredirect') {window.location.href = response.headers.get('Location'); // headers 是空的!}
});

🔍 扩展:还有哪些情况会导致 Status 0?

除了 redirect: 'manual' 导致的 opaque-redirect 外,status 0 还可能由以下原因引起:

原因 说明
网络连接问题 网络断开、WiFi 信号差、飞行模式等
跨域请求被阻止 CORS 配置不当,OPTIONS 预检失败
请求被取消 页面刷新、导航导致请求被中断
协议混合问题 HTTPS 页面请求 HTTP 资源被浏览器阻止
DNS 解析失败 域名无法解析

所以,当你遇到 status 0 时,可以先按以下步骤快速排查:

  1. 打开浏览器开发者工具 → Network 面板
  2. 查看请求是否真的发出了?状态列显示什么?
  3. 如果有请求但状态为 (failed)(canceled),检查网络和 CORS
  4. 如果请求显示为 302 但代码里报 status 0,极大概率就是本文的问题

💡 一个真实案例

有开发者在微信公众号 H5 开发中遇到过类似问题:iOS 10 系统下,设置了自定义 header 后,所有请求都返回 status 0。排查发现是自定义 header 触发了 CORS 预检,而 iOS 10 对 CORS 预检的兼容性有问题,后端返回的 Access-Control-Allow-Headers: * 不被识别,导致真正的请求没有被发送。

解决方法是将 * 改为明确列出的 header 名称:

Access-Control-Allow-Headers: content-type, auth

这个案例告诉我们:status 0 是浏览器层面的“请求没发出去”或“响应被拦截”,通常不是后端业务错误,要从前端/网络层面找原因。

🎓 学到的教训

  1. 不要过度设计 - 浏览器的默认行为通常是最好的
  2. 理解 HTTP 状态码 - Status 0 不代表服务器错误,而是网络层面的问题
  3. 善用调试工具 - Network 面板能看到请求的详细信息
  4. 了解 Fetch API - 各种参数的含义和使用场景,特别是 redirect 这个容易被忽视的选项
  5. 遇到 status 0,先检查网络和配置,再怀疑后端 - 因为请求根本没到服务器

🔗 相关资源

  • MDN - Fetch API
  • MDN - Request.redirect
  • HTTP 重定向详解
  • Fetch 规范 - opaque-redirect 响应类型

💬 互动话题

你在开发中遇到过哪些诡异的 HTTP 错误?欢迎在评论区分享你的故事!

👍 如果这篇文章帮到了你,请点赞、在看、转发三连!


希望这篇推文能帮助更多开发者避开这个坑!🚀

http://www.jsqmd.com/news/571765/

相关文章:

  • 网络调试无从下手?Fiddler中文版让HTTP问题排查效率提升10倍的秘密
  • Voron 2.4 3D打印机构建指南:从零件到精度的系统实践
  • alist-strm实战指南:自动化strm文件管理完整方案
  • 闲置天猫超市卡别浪费!盘点3种常规回收方法,安全又省心 - 京回收小程序
  • 新手友好:在快马平台通过实操理解Harness Engineering的GitOps与自动化
  • 2026北京收纳整理公司排名实测:搬家猫搬家电话010-62898299 - 博客湾
  • 2026 年四川塑木地板优质厂家 实力可靠口碑靠前的户外建材生产企业 - 深度智识库
  • Cosmos-Reason1-7B效果展示:天文观测视频中‘卫星轨迹是否符合轨道力学’验证
  • Inconsolata字体高效使用实战指南:提升编程体验的专业字体方案
  • 串口通信中的数据类型转换与共用体应用
  • [C#]在Microsoft DI中使用属性注入
  • Oracle数据库内存结构概述
  • Bouncy Castle实战:5分钟搞定Java自签名证书生成(附常见错误排查)
  • Ostrakon-VL 扫描终端快速上手:Anaconda 环境下的 Python 调用全流程
  • 回转式格栅除污机生产厂家深度调研:技术实力、产品质量与市场口碑综合评测 - 品牌推荐大师
  • 执业药师考试培训机构哪家靠谱?亲测靠谱选课攻略 - 品牌测评鉴赏家
  • Python包管理避坑指南:为什么会出现Ignoring invalid distribution警告?
  • 千问3.5-2B入门教程:支持中文提示词的视觉语言模型,比Qwen-VL更轻更快
  • 基于物联网的指纹密码锁系统设计(有完整资料)
  • HuggingFace Arrow数据集高效加载与内存优化实战指南
  • GLM-Image开源大模型部署:HuggingFace Hub私有模型加载方法详解
  • 保姆级教程:用torchtext搞定AG_NEWS数据集加载与词表构建(避坑指南)
  • PyTorch中dim参数在tf.nn.functional.softmax(x, dim=-1)中的多维解析与应用
  • 乐器弹唱主旋律配合AI编曲软件,原创音乐人做歌曲的编曲伴奏更轻松
  • 2026年温湿度控制器厂家最新推荐榜:拨盘温湿度控制器、固定温湿度控制器、环境温湿度控制器、数显温湿度控制器、液晶温湿度控制器、智能温湿度控制器厂家选择指南 - 海棠依旧大
  • LXC OverlayFS
  • 5步高效掌握B站视频下载:BilibiliDown全流程应用指南
  • 3小时搭建专属中文法律AI助手:ChatLaw实战指南
  • 告别NeRF的慢与笨:用SplaTAM的3D高斯球,在普通笔记本上也能玩转实时RGB-D SLAM
  • Fast-LIVO2实战:如何让海康工业相机与Livox雷达实现时间戳硬同步?