使用fetch()调用API时遭遇Unexpected end of input错误排查求助
Unexpected end of input错误的关键步骤 首先,这个错误几乎肯定和你设置的mode: 'no-cors'有关——这个模式会让浏览器限制你读取响应的内容,哪怕API返回了有效的JSON,你也无法解析它,最终导致response.json()抛出"Unexpected end of input"错误。下面是一步步的排查和修复方案:
1. 立即移除mode: 'no-cors'
当你设置mode: 'no-cors'时,浏览器会将响应标记为opaque(不透明),你无法访问响应的状态码、headers或内容。也就是说,response.json()根本无法拿到任何可解析的内容,自然会报错。
如果目标API支持CORS(即它的响应头包含Access-Control-Allow-Origin),直接删除这一行即可。如果API不支持CORS,你需要通过后端代理来转发请求(比如用Node.js、PHP或者Nginx做中间层),不能直接从前端调用。
2. 统一请求头的设置
你的代码里同时用了Headers对象和fetch配置里的headers字段,可能会导致冲突。建议把所有请求头统一放到fetch的headers里,或者用Headers对象一次性添加:
// 用Headers对象统一设置的写法 const headers = new Headers(); headers.append('Authorization', 'Basic ' + window.btoa("user" + ':' + "pass")); headers.append('Content-Type', 'application/json');
或者直接在fetch配置里简写:
headers: { 'Authorization': `Basic ${window.btoa("user:pass")}`, 'Content-Type': 'application/json' }
3. 先验证响应的实际内容
在解析JSON之前,先确认API返回的是不是有效的JSON。你可以修改代码,先读取响应文本,看看实际返回的是什么:
.then(response => { if (!response.ok) { throw new Error(`请求失败,状态码:${response.status}`); } return response.text(); // 先获取原始文本内容 }) .then(rawText => { console.log('原始响应内容:', rawText); try { const data = JSON.parse(rawText); console.log('解析后的JSON:', data); } catch (e) { console.error('响应不是有效的JSON:', e); } })
这能帮你排查:是不是API返回了错误页面(比如404、500的HTML),或者返回了空内容,这些都会导致解析JSON失败。
4. 清理URL的冗余字符
你的请求URL末尾有个多余的?,虽然大部分服务器会忽略,但最好去掉,避免潜在的路由匹配问题:'https://www.api-endpoint.com/cat1/api/search?' → 'https://www.api-endpoint.com/cat1/api/search'
修复后的完整代码
function postData(url = '', data = {}) { const authToken = window.btoa("user" + ':' + "pass"); return fetch(url, { method: 'POST', cache: 'no-cache', credentials: 'include', headers: { 'Authorization': `Basic ${authToken}`, 'Content-Type': 'application/json' }, redirect: 'follow', referrer: 'no-referrer', body: JSON.stringify(data), }) .then(response => { if (!response.ok) { throw new Error(`请求失败,状态码:${response.status}`); } return response.json(); }) .catch(error => console.error('请求错误:', error)); } // 调用时去掉URL末尾的? postData('https://www.api-endpoint.com/cat1/api/search', { "searchID": "710", "isTagged": true }) .then(data => console.log('响应数据:', data)) .catch(error => console.error('Fetch错误:', error));
额外注意:如果API不支持CORS
如果目标API确实没有配置CORS头,你必须通过后端代理来转发请求。比如用Node.js写一个简单的代理:
// Node.js代理示例(需先安装express和node-fetch) const express = require('express'); const fetch = require('node-fetch'); const app = express(); app.use(express.json()); app.post('/proxy-search', async (req, res) => { try { const apiResponse = await fetch('https://www.api-endpoint.com/cat1/api/search', { method: 'POST', headers: { 'Authorization': 'Basic ' + Buffer.from("user:pass").toString('base64'), 'Content-Type': 'application/json' }, body: JSON.stringify(req.body) }); const data = await apiResponse.json(); res.json(data); } catch (error) { res.status(500).json({ error: error.message }); } }); app.listen(3000, () => console.log('代理服务器运行在3000端口'));
然后前端请求这个代理地址:postData('http://localhost:3000/proxy-search', ...)
内容的提问来源于stack exchange,提问作者youwhatmate

