上周有人发来一张截图,说他调 QQ 邮箱相关的接口,返回一句「禁止get方法调用」,参数检查了好几遍都没问题。这类报错其实跟参数无关,是服务端在入口就把请求挡了:这个接口只接受 POST,你发的是 GET。
为什么会禁 GET
GET 在 HTTP 规范里是只读语义,会被浏览器、代理、CDN 缓存,也会留在访问日志和历史里。发邮件、改设置、删邮件这类有副作用的操作,如果允许 GET,一条链接就能被人诱导触发,所以接口层通常直接拒绝。返回的往往不是 405,而是业务自定义的一句话,看起来像权限问题,容易误导。
先确认实际发出的是什么方法
最常见的三种情况:在浏览器地址栏直接敲接口地址,那必然是 GET;表单没写 method,浏览器默认也是 GET;用了某个 HTTP 库,默认方法就是 GET 而你没改。
# 错的:默认 GET
curl "https://api.example.com/mail/send?to=xxx"
# 对的:显式 POST,参数放 body
curl -X POST "https://api.example.com/mail/send" \
-H "Content-Type: application/json" \
-d '{"to":"xxx@qq.com","subject":"test"}'抓包看一眼请求行最直接。浏览器 F12 的 Network 里,Method 那一列写的就是真实方法,比自己猜快得多。
QQ 邮箱本身要注意的两点
如果是用 SMTP 发信,那跟 HTTP 方法无关,SMTP 是独立协议,465 走 SSL、587 走 STARTTLS,登录用授权码而不是 QQ 密码。很多人把授权码当密码填,报的是认证失败,方向就偏了。如果用第三方网关转发,则要看清文档要求的方法和 Content-Type,格式不对也可能返回类似拦截提示。
排查顺序
- 看请求行:抓包确认是 GET 还是 POST,别只看代码。
- 看重定向:301、302 会把 POST 变成 GET,跟着跳转一次方法就丢了。
- 看网关:Nginx、WAF 有时会把异常请求统一改写成一句提示。
- 看文档:确认接口要求的 method、Content-Type、鉴权头是否齐全。
重定向这条特别隐蔽:代码写的是 POST,服务端返回 302 指向带斜杠的地址,客户端跟过去方法就降级成 GET 了。把地址的斜杠补齐,或者关掉自动跟随即可。
最后提醒:涉及发信、扣费、状态变更的接口一律用 POST,参数放 body,既符合规范,也避免特殊字符的编码问题。