使用Graph API的Python文件上传脚本报400错误:Content-Range头异常
解决分片上传中Content-Range头部错误的问题
问题根源分析
缩进错误导致仅上传空chunk
你的PUT请求代码写在while循环外部,循环结束后chunk已为空,此时发送的请求必然触发Content-Range无效的错误。必须将PUT请求放到循环内部,保证每个分片都能被正确上传。Content-Range计算逻辑错误
- 重复调用
f.seek(0, 2)会频繁将文件指针移到末尾,既导致后续位置计算混乱,也降低了代码效率,应该提前缓存文件总大小。 - 分片起始/结束位置的计算依赖不稳定的指针操作,容易出现边界值错误。
- 重复调用
冗余的Content-Length设置
requests库会自动根据传入的data长度生成Content-Length头部,手动设置可能因计算失误导致与实际发送字节数不匹配,触发服务器校验错误。
修正后的完整代码
headers = { 'Authorization': 'Bearer ' + result['access_token'], "Content-Type": "application/json" } response = requests.post(url, headers=headers) upload_url = response.json()["uploadUrl"] CHUNK_SIZE = 4 * 1024 * 1024 # 4MB with open(file_path, "rb") as f: # 提前获取文件总大小并缓存,避免重复移动指针 file_size = f.seek(0, 2) f.seek(0) # 指针移回文件开头 while True: chunk = f.read(CHUNK_SIZE) if not chunk: break # 计算当前分片的起始与结束字节位置 start = f.tell() - len(chunk) end = f.tell() - 1 # 处理最后一个分片的边界,避免end超出文件实际大小 if end >= file_size: end = file_size - 1 print(f"bytes {start}-{end}/{file_size}") headers = { "Authorization": f"Bearer {result['access_token']}", # 确保token与获取upload_url时一致 "Content-Range": f"bytes {start}-{end}/{file_size}" } # 移除手动设置的Content-Length,交由requests自动处理 response = requests.put(upload_url, headers=headers, data=chunk) print(headers) print(response.status_code) print(response.text) if response.status_code == 201: print("File uploaded successfully") break # 上传完成后退出循环 elif response.status_code in (200, 206): # 部分分片上传成功,继续下一个分片 continue else: print(f"Upload failed with status code {response.status_code}") break
额外说明
- 确保
Authorization中的token与获取upload_url时使用的result['access_token']一致,避免授权错误。 - 多数分片上传接口会返回206(部分内容)表示单个分片上传成功,直到最后一个分片返回201,代码中增加了对该状态码的处理,保证分片能依次完成上传。
- 最后一个分片的end位置做了兜底处理,避免文件大小刚好为CHUNK_SIZE整数倍时出现边界越界问题。
内容的提问来源于stack exchange,提问作者Ruben
相关产品推荐
相关产品推荐

