ScalaJ请求可获取location响应头,Python http.client等方式取不到如何解决
问题原因
核心问题是Python代码中请求体格式与声明的Content-Type不匹配:
- Scala 侧调用
postForm.params()方法时,会自动将入参 Map 序列化为application/x-www-form-urlencoded格式的字符串(形如login=user%40example.com&password=12345678),符合服务端的参数解析要求,认证通过后返回带 Location 头的重定向响应。 - Python 侧虽然请求头声明了
application/x-www-form-urlencoded,但请求体用json.dumps()序列化成了JSON格式,服务端无法正确解析登录参数,认证失败,因此不会返回重定向对应的 Location 响应头。
解决方法
1. 原生 http.client 修复方案
使用 urllib.parse.urlencode 序列化表单参数,不要用JSON序列化:
import http.client import urllib.parse def post_request(url, data, header, path="/"): conn = http.client.HTTPConnection(url) # 序列化表单参数并编码为字节流 encoded_data = urllib.parse.urlencode(data).encode('utf-8') conn.request("POST", path, headers=header, body=encoded_data) return conn.getresponse() auth = {'login': 'user@example.com', 'password': '12345678'} response3 = post_request( url, header={'Content-Type': 'application/x-www-form-urlencoded'}, data=auth, path=location2 ) print(response3.getheader('location'))
2. requests 库简化方案(推荐)
requests 库会自动处理表单编码逻辑,无需手动序列化参数和设置Content-Type:
import requests auth = {'login': 'user@example.com', 'password': '12345678'} # 若需要获取原始3xx响应的Location头,需关闭自动重定向 response = requests.post(f"{url}{location2}", data=auth, allow_redirects=False) print(response.headers.get('location'))
额外注意:如果服务端返回的是3xx重定向状态码,Python的requests、urllib3默认会自动跟随重定向,拿到的是最终页面的响应头,自然不会包含Location字段,这种情况需要关闭自动重定向配置才能拿到原始重定向响应的Location头。
内容的提问来源于stack exchange,提问作者Ayush Goyal
相关产品推荐
相关产品推荐

