我想做什么(在控制器中)
接收请求,基于该请求
发送外部 HTTP 请求
解析响应,基于
返回响应
我计划有多个功能都遵循这种模式。他们一个接一个地被调用。
Symfony 4.3 引入了 HttpClient 组件和 BrowserKit 组件,乍一看似乎符合要求。但事实证明,事情变得更加复杂。外部 HTTP 请求被发送到使用 cookie 跟踪会话的服务器,这应该不会太不寻常。如果在没有 cookie 的情况下发送请求,服务器总是以相同的登录页面内容进行响应。所以我们需要cookie。不用担心,对初始请求的响应带有一个“Set-Cookie”标头,其中包含在后续请求中在“Cookie”标头中发送的 cookie。带有 cookie 的响应的 HTTP 状态是“302 Found”,它在正常的 Web 环境中,使用 Web 浏览器重定向到请求中具有相同 cookie 的下一个页面。在我的 Symfony 控制器中复制这个动作似乎非常棘手。扩展我现在想做的第 2 步:
2.a. 发送外部 HTTP 请求
2.b. 从 302 响应中读取 cookie(不带自动重定向)
2.c. 设置后续请求的“Cookie”头,值来自2.b。
2.d. 将请求发送到新目标(在 302 响应的“Location”标头中设置)
这是控制器中的一些代码:
use Symfony\Component\HttpClient\HttpClient;
use Symfony\Component\HttpClient\Exception\RedirectionException;
use Symfony\Component\HttpFoundation\JsonResponse;
public function init(Request $request): JsonResponse
{
$url = "external url";
$client = HttpClient::create();
try {
$response = $client->request('GET', $url, [
'max_redirects' => -1
]);
} catch (RedirectionException $redirectionException) {
}
return new JsonResponse([], 200);
}
不设置 max_redirects 意味着客户端遵循重定向并最终返回 200 响应而没有任何 cookie。将该值设置为 -1 将引发重定向异常,并且带有 cookie 的 302 响应似乎丢失了。
我也试过 HttpBrowser 组件:
$cookieJar = new CookieJar();
$client = new HttpBrowser(HttpClient::create(), null, $cookieJar);
$client->request('GET', $url);
但是我得到了一个没有 cookie 的 200 响应,因为它会自动跟随重定向。
我知道这里提到的组件是 Symfony 4.3 的新组件并且是“实验性的”,但我也不认为我的任务过于复杂或不寻常。但也许 Symfony 有其他的 http 客户端更适合这项任务?
繁花如伊
芜湖不芜
随时随地看视频慕课网APP