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

Python requests模块headers传参语法导致API返回异常问题

问题背景

编写简易接口测试脚本时,使用Python requests库对两个不同API发起GET请求,采用相同的传参写法得到了差异极大的响应结果,具体表现如下。

错误传参写法测试结果

未显式指定headers关键字参数,直接将请求头字典作为位置参数传入,执行结果:

>> import requests
>> head1 = { 'key' : 'API-key1' }
>> url1 = 'https://url1.com'
>> r1 = requests.get(url1, head1)     ## Notice headers=head1 wasn't used
>> print(r1)
<Response [200]>                      ## Yet a valid response prints out
>> print(r1.json())
{'response': 'valid response'}


>> head2 = { 'key' : 'API-key2' }
>> url2 = 'https://url2.com'
>> r2 = requests.get(url2, head2)     ## But in this instance
>> print(r2)
<Response [401]>
>> print(r2.json())                   ## I get an 401 error
<bound method Response.json of <Response [401]>>

标准传参写法测试结果

改用官方推荐写法,显式通过headers=xxx关键字传参,执行结果:

>> import requests
>> head1 = { 'key' : 'API-key1' }
>> url1 = 'https://url1.com'
>> r1 = requests.get(url1, headers=head1)   ## Using the correct syntax
>> print(r1)
<Response [200]>
>> print(r1.json())                         ## But it received an error
{'response': {'error': [{'msg': 'No API access key supplied'}]}}



>> head2 = { 'key' : 'API-key2' }
>> url2 = 'https://url2.com'
>> r2 = requests.get(url2, headers=head2)   ## This works
>> print(r2)
<Response [200]>
>> print(r2.json())
{'response': 'valid response'}
原因解答

核心前提:requests.get()的官方函数签名为get(url, params=None, **kwargs),第二个位置参数是params(对应URL问号后拼接的查询参数),headers属于关键字参数,必须显式通过headers=xxx的形式传入。如果直接把字典作为第二个位置参数传入,这个字典不会被当做请求头处理,会被自动序列化为URL查询参数附加到请求地址末尾。

两个API的表现差异完全来自接口本身的鉴权逻辑设计区别:

  • 第二个API的实现符合常规接口设计规范:
    • 鉴权逻辑仅从请求头中读取名为key的访问凭证,不会解析URL查询参数中的同名字段
    • 鉴权失败时按HTTP规范返回401状态码
      错误传参时凭证被拼到URL参数里,请求头无有效凭证,返回401;正确传参时凭证在请求头中被正常读取,返回200有效响应,表现完全符合预期。
  • 第一个API存在两处不规范的实现问题,是导致反常表现的根本原因:
    1. 鉴权逻辑仅支持从URL查询参数中读取名为key的访问凭证,没有实现从请求头读取凭证的逻辑,也没有使用行业通用的请求头鉴权字段(比如Authorization、X-API-Key等)。错误传参时key字段刚好被拼到URL查询参数中,歪打正着满足了鉴权要求,所以返回有效响应;正确传参时key被放到请求头里,接口读不到凭证,就返回了「未提供API访问密钥」的错误。
    2. 鉴权失败时没有按HTTP规范返回401状态码,所有场景统一返回200状态码,仅在响应体内标注错误信息,很容易误导调用方判断请求状态。

另外测试中打印第二个API401响应时出现<bound method Response.json of <Response [401]>>,是编写代码时漏写了json后的调用括号(),属于手误导致的小问题,和接口逻辑、传参逻辑无关,补上括号即可正常打印响应内容。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 16:06:30