Node.js获取HubSpot OAuth访问令牌时遇415不支持媒体类型错误
HubSpot OAuth令牌获取415错误排查
问题场景
我在Node.js后端应用中调用HubSpot OAuth接口获取访问令牌,编写的getAccessToken方法始终返回415 Unsupported Media Type错误,但使用CURL调用相同接口却能正常运行。
原Node.js代码
function getAccessToken(code){ const formData = { grant_type: 'authorization_code', client_id: process.env.CLIENT_ID, client_secret: process.env.CLIENT_SECRET, redirect_uri: process.env.REDIRECT_URI, code: code }; axios.post('https://api.hubapi.com/oauth/v1/token', { form: formData }, { headers: { 'Content-Type': 'multipart/form-data' } } ) .then(function (response) { console.log(response); }) .catch(function (error) { console.log(error); }); }
正常运行的CURL命令
curl -X POST https://api.hubapi.com/oauth/v1/token -H "Content-Type: application/x-www-form-urlencoded" -d "grant_type=authorization_code" -d "client_id=yyyy" -d "client_secret=xxx" -d "redirect_uri=http://localhost:3000/api/hubspot/callback&scope=crm.schemas.deals.read%20oauth%20crm.objects.leads.read%20crm.objects.users.read%20crm.objects.contacts.write%20crm.objects.appointments.read%20crm.objects.companies.read%20crm.lists.read%20crm.objects.deals.read%20crm.schemas.contacts.read%20crm.objects.contacts.read%20crm.schemas.companies.read" -d "code=zzzz"
问题原因
你的代码存在两个关键错误:
- 请求头Content-Type不匹配:HubSpot的OAuth令牌接口仅接受
application/x-www-form-urlencoded格式的请求,但你设置了multipart/form-data,这是导致415错误的直接原因。 - 请求体格式错误:Axios发送
application/x-www-form-urlencoded数据时,不需要将参数包裹在form对象中,直接传递参数对象即可;额外的包裹会导致请求体格式不符合接口要求。
修正后的代码
function getAccessToken(code){ const formData = { grant_type: 'authorization_code', client_id: process.env.CLIENT_ID, client_secret: process.env.CLIENT_SECRET, redirect_uri: process.env.REDIRECT_URI, code: code }; axios.post('https://api.hubapi.com/oauth/v1/token', formData, // 直接传递参数对象,Axios自动编码为x-www-form-urlencoded格式 { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } } ) .then(function (response) { console.log(response); }) .catch(function (error) { console.log(error); }); }
可选:手动编码请求体
如果你需要手动处理参数编码,可以使用Node.js内置的querystring模块:
const querystring = require('querystring'); function getAccessToken(code){ const formData = { grant_type: 'authorization_code', client_id: process.env.CLIENT_ID, client_secret: process.env.CLIENT_SECRET, redirect_uri: process.env.REDIRECT_URI, code: code }; axios.post('https://api.hubapi.com/oauth/v1/token', querystring.stringify(formData), // 手动编码为x-www-form-urlencoded格式 { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } } ) .then(function (response) { console.log(response); }) .catch(function (error) { console.log(error); }); }
内容的提问来源于stack exchange,提问作者TerenceJackson
相关产品推荐
相关产品推荐

