【问题标题】:How to use Goutte to submit a form and get final URI?如何使用 Goutte 提交表单并获取最终 URI?
【发布时间】:2015-07-01 18:50:25
【问题描述】:

目的是在远程网站上填充form[id=thisAwesomeRemoteForm][action=#]。只有一个字段 (input[name=awesomeField]) 需要填充,然后需要提交表单。作为最终要求,用户需要从我的网站重定向到这个远程网站,就好像它已经在远程网站上提交了表单一样。

长话短说,我需要用户能够点击我的链接,让 PHP 完成这项工作并被重定向到这个远程网站,就好像它已经填写并提交了远程网站上的表单一样。我不必让用户自己填写远程表单。

目前的代码是:

use Goutte\Client;
// ...
public function gotoAction($data)
{
    $client = new Client();
    $crawler = $client->request('GET', self::MY_URL);

    $form = $crawler->filter('form[id=thisAwesomeRemoteForm]')->form();

    $form->setValues(array('awesomeField' => $data));
    $crawler = $client->submit($form);

    return $this->redirect($form->getUri());
}

到目前为止,我被重定向到 form 所在的第一个 URL,而不是 form 应该指向的第一个 URL。不过,该字段填充了正确的数据。

我的代码是否正确以实现我的目的(因此,远程网站可能使用 JavaScript 发送表单或其他内容)还是我遗漏了一些相当明显的东西?

【问题讨论】:

  • 此表单重定向到哪里?你控制它吗? Goutte 请求和重定向之间的请求是否持久。重定向是显示空表单还是表单已经提交?
  • 嗨@A.L!不,我无法控制远程网站上的表格。该表单指向远程服务器上的另一个页面。 persistent request 是什么意思?我不认为表单已提交。
  • 通过 persistent request 我的意思是,从远程服务器的角度来看,Goutte 和您的用户是两个不同的访问者,我不知道您如何获得提交表单的结果并将其显示给用户。
  • 表单操作 url 是同一个页面吗?喜欢同一页面上的帖子?我从未见过使用最后一个 -> 重定向,就像这样 $crawler = $client->submit($form, array('stuff')); echo $crawler->html();
  • 我们在这里谈论什么样的重定向? Location 标头,<meta> 标签,JavaScript sn-p?

标签: php forms symfony web-crawler goutte


【解决方案1】:

Goutte 基本上是 Guzzle 到 Symfony\Browserkit API 的适配器。基于对Goutte\Client 源代码的粗略分析,effectiveUrl() 未被使用或结转。这意味着如果发生重定向,您将不会“捡起它”。

您可以使用以下代码 sn-p 使用基本组件(Guzzle、DomCrawler)轻松地执行相同的功能:

$client = new GuzzleHttp\Client([
    'debug' => true, // only to troubleshoot
);

// Obtain the html page with the form
$request = $client->createRequest('GET', $url);
$response = $client->send($request);
// or $response = $client->get($url);

// create crawler and obtain the form.
$crawler = new Symfony\Component\DomCrawler\Crawler(null, $response->getEffectiveUrl());
$crawler->addContent(
    $response->getBody()->__toString(),
    $response->getHeader('Content-Type')
);

$form = $crawler->form('form_identifier');
$form->setValues($data_array);

//form submission
$request = $client->createRequest(
    $form->getMethod(),
    $form->getUrl(),
    [
        'body' => $form->getPhpValues(),
]);

$response = $client->send($request);

【讨论】:

  • 也许我错过了问题中的某些内容,但 Guzzle 默认使用 cURL,默认设置为自动响应最多五​​个重定向请求。请参阅options list 中的CURLOPT_FOLLOWLOCATIONCURLOPT_MAXREDIRS
猜你喜欢
  • 2016-10-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-30
  • 2011-02-26
  • 1970-01-01
  • 2015-06-25
相关资源
最近更新 更多