node-fetch返回空响应,为何与REST客户端表现不一致?
问题描述
使用node-fetch 2.6.6请求OAUTH2 Access Token(JWT)时返回空响应{"size": 0, "timeout": 0},但用REST客户端以表单编码提交相同参数能成功获取令牌。
我的代码
async function getAccessToken() { if (argumentParserResult.authenticationScheme == 'OAUTH2') { const fetch = require('node-fetch'); const url = argumentParserResult.resourceUrl; let body = { 'grant_type': 'client_credentials', 'client_id': argumentParserResult.clientId, 'scope': argumentParserResult.clientScope, 'client_secret': argumentParserResult.clientSecret } console.log('POST ' + argumentParserResult.authorizationUrl); console.log(JSON.stringify(body)); let response = await fetch(argumentParserResult.authorizationUrl, { method: 'POST', body: JSON.stringify(body) }); console.log('Access token request repsonse: ' + JSON.stringify(response)); process.exit(1); } }
REST客户端请求详情
POST指定URL,表单编码参数:
grant_type: client_credentials client_id: some-client-id scope: some-long-scope-string client_secret: client-secret
问题原因及修复
你的代码存在两个核心问题:
- 请求体格式不匹配:OAUTH2的
client_credentials模式要求请求体使用application/x-www-form-urlencoded(表单编码)格式,但你用JSON.stringify(body)发送了JSON格式的请求体,服务端无法识别解析,因此返回空响应。 - 未正确获取响应内容:直接对fetch返回的
Response对象执行JSON.stringify()是错误的,该对象是响应元数据容器,不是实际的响应体内容,需要调用专属方法解析。
修正后的代码
async function getAccessToken() { if (argumentParserResult.authenticationScheme == 'OAUTH2') { const fetch = require('node-fetch'); // 用URLSearchParams构造表单编码的请求体,符合OAUTH2要求 const body = new URLSearchParams({ 'grant_type': 'client_credentials', 'client_id': argumentParserResult.clientId, 'scope': argumentParserResult.clientScope, 'client_secret': argumentParserResult.clientSecret }); console.log('POST ' + argumentParserResult.authorizationUrl); console.log(body.toString()); const response = await fetch(argumentParserResult.authorizationUrl, { method: 'POST', body: body, headers: { // 显式设置Content-Type,node-fetch 2.x会自动识别URLSearchParams并设置,但显式声明更稳妥 'Content-Type': 'application/x-www-form-urlencoded' } }); // 解析响应体的实际内容 const tokenData = await response.json(); console.log('Access token response data: ', tokenData); process.exit(1); } }
额外说明
- node-fetch 2.x中,当请求体为
URLSearchParams类型时,会自动设置Content-Type请求头,但显式声明可以避免潜在的兼容问题。 - 如果服务端返回非JSON格式的响应,可以改用
response.text()来获取内容。
内容的提问来源于stack exchange,提问作者Woodsman
相关产品推荐
相关产品推荐

