从JMeter迁移脚本到Locust调用/api/v1/authenticate报405错误,参考StackOverflow方案未解决
问题根因定位
405 "Method Not Allowed" 报错的核心触发逻辑是服务端(包括前置的WAF、路由网关)判定当前发往目标路径的请求,不符合该路径预设的访问规则,并非单纯的参数序列化格式错误,结合从JMeter迁移脚本的场景,可按以下步骤排查修复:
- 第一步:核对接口实际支持的请求方法
对照原JMeter脚本里HTTP采样器的方法配置,不要主观认定登录接口就一定用POST。如果原JMeter脚本配的是GET方法,但你在Locust里写了POST,服务端会直接返回405而非清晰的方法提示。 - 第二步:修正完全失配的请求头配置
你当前脚本里的请求头全是浏览器导航跳转网页时的专用请求头,根本不匹配API类接口的请求特征:Sec-Fetch-Mode: navigate、Sec-Fetch-Dest: document这类头会明确告知服务端“这是用户点击链接跳转整页的请求”,绝大多数后端路由防护规则会直接拦截这类发往API路径的网页类请求,直接返回405- 请求头字段存在拼写错误:
Upgrade-Insecure-Requestz正确字段为Upgrade-Insecure-Requests,这类错误字段会触发WAF的爬虫识别规则,直接拦截请求 - 缺失API请求必需的
Content-Type头:你用data=json.dumps(...)传参时,客户端默认会把Content-Type设为application/x-www-form-urlencoded,和你传的JSON请求体格式完全不匹配,严格的后端服务会因为路由规则不匹配,返回405而非标准的415“不支持的媒体类型”错误。
- 第三步:调整参数传递方式
不需要手动用json.dumps序列化参数后传给data字段,Locust的内置客户端原生支持json=参数传字典结构,会自动补上符合JSON规范的Content-Type头,减少格式失配的概率。 - 第四步:核对路径与Host配置的匹配性
确认Locust里配置的host值和接口实际所在的域名完全一致,没有多余的斜杠、路径前缀,避免因为路径匹配错误落到别的路由规则上触发405。
参考修正脚本
from locust import HttpUser, task, between, tag class QuickstartUser(HttpUser): wait_time = between(1, 2.5) # 与接口实际所在域名完全匹配,无多余路径 host = "https://mywebsite" @tag('login') @task def Login(self): response = self.client.post( "/api/v1/authenticate", # 直接传字典,无需手动序列化 json={"username":"user1","password":"Test1234","mode":"chrome"}, headers={ # 去掉所有导航类请求头,只保留接口必需的最小头集 "Accept": "application/json", "Content-Type": "application/json" } ) # 开启状态码校验,方便定位错误 response.raise_for_status()
快速验证方法
- 用curl命令直接发起请求验证服务端规则:
curl -X POST https://mywebsite/api/v1/authenticate -H "Content-Type: application/json" -d '{"username":"user1","password":"Test1234","mode":"chrome"}'- 如果curl能正常返回登录响应,说明问题完全来自Locust脚本的请求头、传参、配置问题
- 如果curl直接返回405,说明接口本身不支持POST方法,需要回头核对原JMeter脚本的方法配置,不要凭经验写接口请求方法。
内容的提问来源于stack exchange,提问作者Akmal Mahathir
相关产品推荐
相关产品推荐

