使用 trio 的请求询问 returns 与请求和 aiohttp 不同的响应

Request using trio asks returns a different response than with requests and aiohttp

好的,你好,所以我正在尝试使用 trio 和 asks (https://asks.readthedocs.io/) 在我的 webapp 中实现 optical(会员卡服务)。

所以我想向他们发送请求 api: 这里使用请求:

import requests
r = requests.post("https://merchant.opticard.com/public/do_inquiry.asp", data={'company_id':'Dt', 'FirstCardNum1':'foo', 'g-recaptcha-response':'foo','submit1':'Submit'})

这会return"Invalid ReCaptcha"这很正常,也是我想要的

同样使用 aiohttp:

import asyncio
import aiohttp

async def fetch(session, url):
    async with session.post(url, data={'company_id':'Dt', 'FirstCardNum1':'foo', 'g-recaptcha-response':'foo','submit1':'Submit'} ) as response:
        return await response.text()

async def main():
    async with aiohttp.ClientSession() as session:
        html = await fetch(session, 'https://merchant.opticard.com/public/do_inquiry.asp')
        print(html)

loop = asyncio.get_event_loop()
loop.run_until_complete(main())

现在这也是 returns "Invalid ReCaptcha",所以一切都很好。

但是现在,使用 trio/asks:

import asks
import trio

async def example():
    r = await asks.post('https://merchant.opticard.com/public/do_inquiry.asp', data={'company_id':'Dt', 'FirstCardNum1':'foo', 'g-recaptcha-response':'foo','submit1':'Submit'})
    print(r.text)
trio.run(example)

这个return与'Your session has expired to protect your account. Please login again.'完全不同的响应,这个error/message在输入无效的url如'https://merchant.opticard.com/do_inquiry.asp' instead of 'https://merchant.opticard.com/public/do_inquiry.asp'时可以正常访问.

我不知道这个错误是从哪里来的,我尝试设置 headers、cookies、编码,但似乎没有任何效果。我尝试重现这个问题,但我设法用 aiohttp 和 requests 重现结果的唯一方法是设置不正确的 url,例如“https://merchant.opticard.com/do_inquiry.asp' instead of 'https://merchant.opticard.com/public/do_inquiry.asp”。

这一定是 asks 的问题,可能是编码或格式的问题,但我已经使用 asks 一年多了,从来没有遇到过简单的 post 数据请求会 return 与其他地方相比,要求不同。而且我很困惑,因为我不明白为什么会这样,这不可能是请求部分的格式错误,因为如果是这样的话,为什么这是第一次使用它超过一年?

这是收到 non-standard 位置时如何处理重定向的错误。

服务器 returns 一个带有 Location: inquiry.asp?... 的 302 重定向,而询问期望它是一个完整的 URL。您可能想向 asks 提交错误报告。


我是怎么找到这个的?一个好的方法是使用代理(例如 mitmproxy)来检查流量。但是询问不支持代理。所以我转而使用 wireshark 并使用 a program 提取 TLS 密钥,以便 wireshark 可以解密流量。