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

如何移除Discord REST API响应中的分块传输相关多余字符?

解决Discord OAuth2 Token响应的分块编码解析问题

你遇到的问题是因为Discord返回的响应使用了分块编码(Transfer-Encoding: chunked),直接分割\r\n\r\n提取的响应体包含分块长度标识(如de)和结束标记(如0),导致json.loads无法解析。下面是两种可靠的解决方法:

方案一:使用成熟HTTP库(推荐)

直接用requests库处理HTTP请求,它会自动处理分块编码、头解析和错误处理,代码简洁且不易出错:

import requests

def request_access_token(client_id: str, client_secret: str, code: str, redirect_uri: str) -> dict:
    url = "https://discord.com/api/oauth2/token"
    data = {
        "client_id": client_id,
        "client_secret": client_secret,
        "grant_type": "authorization_code",
        "code": code,
        "redirect_uri": redirect_uri
    }
    response = requests.post(url, data=data)
    response.raise_for_status()  # 主动抛出HTTP错误,方便调试
    return response.json()

方案二:手动解析分块编码(原生Socket)

如果必须使用原生Socket,需要严格按照HTTP分块编码的规范解析响应体,去掉分块长度标识和分隔符:

import socket
import ssl
import json

def request_access_token(client_id: str, client_secret: str, code: str, redirect_uri: str) -> dict:
    host = "discord.com"
    path = "/api/oauth2/token"
    port = 443

    data = f"client_id={client_id}&client_secret={client_secret}&grant_type=authorization_code&code={code}&redirect_uri={redirect_uri}"
    request = f"POST {path} HTTP/1.1\r\nHost: {host}\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: {len(data)}\r\nConnection: close\r\n\r\n{data}"

    context = ssl.create_default_context()
    with socket.create_connection((host, port)) as sock:
        with context.wrap_socket(sock, server_hostname=host) as ssock:
            ssock.sendall(request.encode())

            response = b""
            while True:
                chunk = ssock.recv(1024)
                if not chunk:
                    break
                response += chunk

    # 分离HTTP响应头和响应体
    header_part, body_part = response.split(b"\r\n\r\n", 1)

    # 解析分块编码数据的函数
    def parse_chunked_data(chunked_data):
        raw_body = b""
        remaining_data = chunked_data
        while remaining_data:
            # 提取分块长度(十六进制字符串)
            length_line, remaining_data = remaining_data.split(b"\r\n", 1)
            chunk_length = int(length_line, 16)
            if chunk_length == 0:  # 分块结束标记
                break
            # 提取当前分块的内容
            raw_body += remaining_data[:chunk_length]
            # 跳过内容后的\r\n分隔符
            remaining_data = remaining_data[chunk_length + 2:]
        return raw_body

    # 判断响应是否使用分块编码
    headers = header_part.decode().split("\r\n")
    is_chunked = any("Transfer-Encoding: chunked" in header for header in headers)

    if is_chunked:
        body_content = parse_chunked_data(body_part)
    else:
        body_content = body_part

    return json.loads(body_content.decode())

关键说明:

分块编码的结构是:

  • 每块开头是十六进制的长度值 + \r\n
  • 接着是对应长度的内容 + \r\n
  • 最后以0\r\n\r\n表示所有分块结束

手动解析时需要严格按照这个结构提取内容,不能靠简单的字符串替换,否则遇到复杂分块场景(比如多块、长度带扩展参数)会出错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 00:32:40