Node.js服务器发起HTTPS请求遭Forbidden,问题出在哪?
Node.js请求Discogs收藏夹API返回Forbidden的问题
我尝试通过Node.js服务器向Discogs收藏夹API发起GET请求,但请求返回Forbidden。当前流程为:HTML按钮通过fetch API触发向Node服务器的GET请求,Node服务器将请求路由至处理函数,由该函数向Discogs的/users/{username}/collection/folders端点发起HTTPS请求。此请求需要身份验证,此前直接在前端通过fetch API携带API密钥作为Authorization头,可成功完成GET和POST请求,但在Node服务器端使用相同方式授权却失败。
实际输出
浏览器实际输出
控制台打印node server response not ok
Node终端实际输出
打印Discogs返回的Forbidden错误内容
相关代码
HTML及脚本
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Test GET request to Discogs API</title> </head> <body> <form> <input type="button" value="Get Folders" onclick="getFolders()"> </form> <script> async function getFolders() { try { const res = await fetch('http://localhost:1000/getfolders') if(!res.ok) { console.log('node server response not ok') } else { const jsonResponse = await res.json() console.log('hello' + jsonResponse) } } catch (error) { console.log('there was an error' + error) } } </script> </body> </html>
Node.js服务器代码
const http = require('http') const https = require('https') const url = require('url') const port = 1000 const username = 'someUsername' const apiKey = 'apikey123456789' const server = http.createServer((req, res) => { const {method} = req switch(method) { case 'GET': return handleGetRequest(req, res) default: throw new Error(`Unsupported request method: ${method}`) } }) server.listen(port, () => { console.log('Server listening on port:' + port); }) const handleGetRequest = (req, res) => { const options = { hostname: 'api.discogs.com', path: `/users/${username}/collection/folders`, headers: { 'Content-Type': 'application/json', Authorization: `Discogs token=${apiKey}` } } const request = https.request(options, response => { let data = '' response.on('data', (chunk) => { data += chunk }) response.on('end', () => { console.log('Retrieved Data:', data) res.setHeader("Access-Control-Allow-Origin", "*") const jsonData = JSON.stringify(data) res.end(jsonData) }) }) request.end() }
问题排查与解决方案
- 授权头格式验证
- 若使用的是User Token,确保
apiKey变量存储的是Discogs生成的用户令牌,而非Consumer Key。 - 若使用的是Consumer Key/Secret,需修改Authorization头格式为:
Authorization: `Discogs key=${consumerKey}, secret=${consumerSecret}`
- 若使用的是User Token,确保
- 请求路径与用户名校验
确认username变量对应的是Discogs平台上真实存在的用户名,路径拼接无拼写错误。 - 添加错误处理
原代码未处理Discogs请求的错误事件,添加request.on('error')监听可以捕获网络或请求异常,便于排查问题:request.on('error', (err) => { console.error('Discogs请求出错:', err) res.setHeader("Access-Control-Allow-Origin", "*") res.writeHead(500) res.end(JSON.stringify({error: err.message})) }) - 返回数据优化
原代码中JSON.stringify(data)会将已经是JSON字符串的响应再次转义,直接返回原始data即可:res.writeHead(response.statusCode) res.end(data) - 路径匹配优化
可添加路径判断,只处理/getfolders路径的请求,避免无效请求:const pathname = url.parse(req.url).pathname if (pathname !== '/getfolders') { res.writeHead(404) return res.end('Not Found') }
内容的提问来源于stack exchange,提问作者gbillsonuk
相关产品推荐
相关产品推荐

