php Guzzle中如何读取响应有效URL~6.0

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30682307/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 21:59:30  来源:igfitidea点击:

How to read the response effective URL in Guzzle ~6.0

phpguzzlepsr-7

提问by joserobleda

I've been searching for about 2 hours and I can't figure it out how to read the final response uri.

我已经搜索了大约 2 个小时,但我不知道如何阅读最终响应 uri。

In previous versions of PHP Guzzleyou just call $response->getEffectiveUrl()and you get it.

在以前版本的 PHP Guzzle 中,您只需调用即可$response->getEffectiveUrl()获取。

I expected to have something similar in the new version so the final code looks like this:

我希望在新版本中有类似的东西,所以最终的代码是这样的:

$response = $httpClient->post('http://service.com/login', [
    'form_params' => [
        'user'   => $user,
        'padss'  => $pass,
    ]
]);

$url = $response->getEffectiveUrl();

But in the latest version $responseis now a GuzzleHttp\Psr7\Responseand there is no method which allow me to retrieve the uri.

但是在最新版本$response中,现在GuzzleHttp\Psr7\Response没有方法可以让我检索 uri。

I read about the redirects here (http://guzzle.readthedocs.org/en/latest/quickstart.html#redirects) but it says nothing about

我在这里阅读了重定向(http://guzzle.readthedocs.org/en/latest/quickstart.html#redirects),但它没有说明

UPDATE: The 6.1 version now allows you to easily do this:

更新:6.1 版本现在允许您轻松执行此操作:

https://stackoverflow.com/a/35443523/1811887

https://stackoverflow.com/a/35443523/1811887

Thanks @YauheniPrakopchyk

谢谢@YauheniPrakopchyk

回答by Yauheni Prakopchyk

Guzzle 6.1 solution right from the docs.

来自文档的Guzzle 6.1 解决方案。

$client = new \GuzzleHttp\Client();

$client->get('http://some.site.com', [
    'query'   => ['get' => 'params'],
    'on_stats' => function (TransferStats $stats) use (&$url) {
        $url = $stats->getEffectiveUri();
    }
])->getBody()->getContents();

echo $url; // http://some.site.com?get=params

回答by bgaluszka

You can check what redirects your request had byt setting track_redirectsparameter:

您可以通过设置track_redirects参数检查您的请求有哪些重定向:

$client = new \GuzzleHttp\Client(['allow_redirects' => ['track_redirects' => true]]);

$response = $client->request('GET', 'http://example.com');

var_dump($response->getHeader(\GuzzleHttp\RedirectMiddleware::HISTORY_HEADER));

If there were any redirects last one should be your effective url otherewise your initial url.

如果有任何重定向,最后一个应该是您的有效网址,否则就是您的初始网址。

You can read more about allow_redirectshere http://docs.guzzlephp.org/en/latest/request-options.html#allow-redirects.

你可以allow_redirects在这里阅读更多关于http://docs.guzzlephp.org/en/latest/request-options.html#allow-redirects 的信息

回答by Евгений Грицай

I am using middleware to track requests in the redirect chain and save the last one. The uri of the last request is what you want.

我正在使用中间件来跟踪重定向链中的请求并保存最后一个。最后一个请求的 uri 就是你想要的。

Try this code:

试试这个代码:

$stack = \GuzzleHttp\HandlerStack::create();
$lastRequest = null;
$stack->push(\GuzzleHttp\Middleware::mapRequest(function (\Psr\Http\Message\RequestInterface $request) use(&$lastRequest) {
    $lastRequest = $request;
    return $request;
}));

$client = new Client([
    'handler' => $stack,
    \GuzzleHttp\RequestOptions::ALLOW_REDIRECTS => true
]);

$request = new \GuzzleHttp\Psr7\Request('GET', 'http://httpbin.org/redirect-to?url=http://stackoverflow.com');
$response = $client->send($request);
var_dump($lastRequest->getUri()->__toString());

Result:

结果:

string(24) "http://stackoverflow.com"

Example with class:

类示例:

class EffectiveUrlMiddleware
{
    /**
     * @var \Psr\Http\Message\RequestInterface
     */
    private $lastRequest;

    /**
     * @param \Psr\Http\Message\RequestInterface $request
     *
     * @return \Psr\Http\Message\RequestInterface
     */
    public function __invoke(\Psr\Http\Message\RequestInterface $request)
    {
        $this->lastRequest = $request;
        return $request;
    }

    /**
     * @return \Psr\Http\Message\RequestInterface
     */
    public function getLastRequest()
    {
        return $this->lastRequest;
    }
}

$stack = \GuzzleHttp\HandlerStack::create();
$effectiveYrlMiddleware = new EffectiveUrlMiddleware();
$stack->push(\GuzzleHttp\Middleware::mapRequest($effectiveYrlMiddleware));

$client = new Client([
    'handler' => $stack,
    \GuzzleHttp\RequestOptions::ALLOW_REDIRECTS => true
]);

$request = new \GuzzleHttp\Psr7\Request('GET', 'http://httpbin.org/redirect-to?url=http://stackoverflow.com');
$response = $client->send($request);
var_dump($effectiveYrlMiddleware->getLastRequest()->getUri()->__toString());

回答by Artur Bodera

I think it's best to use response headers to store this information. I wrote a simple class that saves effective url in X-GUZZLE-EFFECTIVE-URLheader:

我认为最好使用响应头来存储这些信息。我写了一个简单的类,将有效的 url 保存在X-GUZZLE-EFFECTIVE-URL标题中:

https://gist.github.com/Thinkscape/43499cfafda1af8f606d

https://gist.github.com/Thinkscape/43499cfafda1af8f606d

Usage:

用法:

<?php
use GuzzleHttp\Client;
use Thinkscape\Guzzle\EffectiveUrlMiddleware;

// Add the middleware to stack and create guzzle client
$stack = HandlerStack::create();
$stack->push(EffectiveUrlMiddleware::middleware());
$client = new Client(['handler' => $stack]);

// Test it out!
$response = $client->get('http://bit.ly/1N2DZdP');
echo $response->getHeaderLine('X-GUZZLE-EFFECTIVE-URL');

回答by Sebastien Horin

Accepted answer didn't work for me but led me on the way:

接受的答案对我不起作用,但引导我前进:

$client = new \GuzzleHttp\Client();
$client->request('GET', $url, [
    'on_stats' => function (\GuzzleHttp\TransferStats $stats) {
        echo($stats->getHandlerStats()['redirect_url']);
    }
]);

回答by Madan Sapkota

You need to add track_redirectsexplicitly in your Guzzle client.

您需要track_redirects在 Guzzle 客户端中明确添加。

$client = new GuzzleHttp\Client(['allow_redirects' => ['track_redirects' => true]]);
$response = $client->head('http://shop.imeldas.com');
$redirects = $response->getHeader(GuzzleHttp\RedirectMiddleware::HISTORY_HEADER);
$effectiveUrl = end($redirects);

The $redirectsmay contains...

$redirects5月包含...

0element, if no redirect.

0元素,如果没有重定向。

1..nelements, if one or more redirects.

1..n元素,如果一个或多个重定向。

回答by marcosh

I'm not an expert in the subject but, from what I understand, the effective url is not something that is defined in a general HTTP message. I think is is something related to Curl and since Guzzle can use any HTTP handler to send requests (see here), the information is not necessarily present.

我不是该主题的专家,但据我所知,有效 url 不是在一般 HTTP 消息中定义的内容。我认为 is 与 Curl 相关,并且由于 Guzzle 可以使用任何 HTTP 处理程序发送请求(请参阅此处),因此信息不一定存在。