You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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()
}

问题排查与解决方案

  1. 授权头格式验证
    • 若使用的是User Token,确保apiKey变量存储的是Discogs生成的用户令牌,而非Consumer Key。
    • 若使用的是Consumer Key/Secret,需修改Authorization头格式为:
      Authorization: `Discogs key=${consumerKey}, secret=${consumerSecret}`
      
  2. 请求路径与用户名校验
    确认username变量对应的是Discogs平台上真实存在的用户名,路径拼接无拼写错误。
  3. 添加错误处理
    原代码未处理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}))
    })
    
  4. 返回数据优化
    原代码中JSON.stringify(data)会将已经是JSON字符串的响应再次转义,直接返回原始data即可:
    res.writeHead(response.statusCode)
    res.end(data)
    
  5. 路径匹配优化
    可添加路径判断,只处理/getfolders路径的请求,避免无效请求:
    const pathname = url.parse(req.url).pathname
    if (pathname !== '/getfolders') {
        res.writeHead(404)
        return res.end('Not Found')
    }
    

内容的提问来源于stack exchange,提问作者gbillsonuk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 01:35:16