是否可以通过PHP重定向发送POST数据?

时间:2015-09-04 00:59:33

标签: php web-services http httprequest http-redirect

更新:这不是How do I send a POST request with PHP?的重复。那里的解决方案对我不起作用,他们只是输出请求的结果,我不想这样做,我想把用户发送到外部网站,它是用于信用卡支付处理的安全网站。 /强>

更新2:我在下面添加了一张图表,试图清楚地解释我正在尝试做什么

这是我正在尝试做的事情:

  1. 将html表单提交给php脚本

  2. php脚本对数据进行一些处理,然后通过POST请求将数据提交到外部网站

  3. 我不希望在我的PHP脚本中收到POST请求的结果,而只是想将用户发送到他们看到POST结果的外部站点

  4. 我认为curl不适合这项任务,因为我对收到请求的结果不感兴趣,我只想将用户发送到下一个站点,就好像他们直接提交了表单一样。 / p>

    换句话说,我想将表单提交到外部网站,但我想首先将其提交到我自己的脚本,这样我就可以处理数据并发送电子邮件通知,然后通过一些内容提交到外部网站添加了新的计算数据。

    我能想到的一种方法是将新表单输出作为隐藏字段与javascript一起输出以自动提交表单,但必须有一种更直接,更健壮的方式来完成它而不依赖于javascript。也许通过操纵标题,或者可能已经有一个PHP函数来简单地提交一个帖子请求并重定向到结果?

    What I'm trying to do

9 个答案:

答案 0 :(得分:7)

在我看来,在发送POST数据时,您正尝试从一个页面重定向到另一个页面。我担心用PHP不可能。

我能想到的最简单的解决方法是使用cURL(1)将您的$_POST数据转发到另一台服务器,(2)从该服务器接收结果,然后(3)简单地重定向到另一台服务器页。虽然它需要总共3个HTTP请求(对于这么简单的问题有点多),但它或多或少地实现了您尝试实现的目标。

让我将这种方法分解为你在问题中提到的三个步骤:

对于第1步,任何HTML表单都可以,只要它有"方法"属性值为#34; post"。如果您想在不使用JavaScript的情况下提交表单,请确保它有一个"提交"按钮。这会将您的数据提交到" action"中定义的页面。按下提交按钮时表单的属性:

示例HTML:

<form action="action_page.php" method="post">
    First name:<br />
    <input type="text" name="firstname" value="Mickey"><br />

    Last name:<br />
    <input type="text" name="lastname" value="Mouse" /><br /><br />

    <input type="submit" value="Submit" />
</form>

对于第2步,您需要创建一个名称与&#34; action&#34;的值相同的页面。你的表格的属性。在我们的示例中,那将是action_page.php。在这里,您检查$_POST是否包含您提交的表单字段的任何值。在案例或我们的例子中,你可以这样:

if (isset($_POST['firstname']) && isset($_POST['lastname'])) {
    // Do the stuff you want to do on your own server here!
} else {
    // Do nothing here!
}

对于第3步,您需要使用刚从HTML表单收到的$_POST数据发出第二个POST请求。最简单的方法是使用cURL。然后,根据第二个POST请求的输出,将用户重定向到第二页。

为了提高示例代码的可读性,我将与cURL请求相关的所有代码放入函数中:

function forwardRequest($url, $data) {
    $result = [
        'status' => NULL,
        'last_url' => NULL,
        'response' => NULL
    ];
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    $result['response'] = curl_exec($ch);
    $result['status'] = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    $result['last_url'] = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL);
    curl_close ($ch);
    return $result;
}

if (isset($_POST['firstname']) && isset($_POST['lastname'])) {
    // Do the stuff you want to do on your own server here!

    $result = forwardRequest("http://www.example.com/processdata.php", $_POST);

    if ($result['status'] === 200) {
        header('Location: http://www.example.com/ok.php');
    } else {
        header('Location: http://www.example.com/error.php');
    }
} else {
    header('Location: http://www.example.com/youshouldnotbehere.php');
}

注1:

我担心,只要数据提交到该系统,就没有通用的方法来确定外部系统上的一切是否顺利。

在我的示例代码中,我使用了您的cURL请求收到的响应的HTTP status code。只有当服务器在该服务器上出现问题时返回不等于200的状态代码时,此解决方案才有效。您需要运行一些测试,看看这种方法是否足以满足您的使用需求。

如果您无法使用状态代码确定一切是否顺利,请考虑查看最后一个有效网址或在您的回复标题中查找线索&amp;你的回复文本。

注2:

您可能只想在服务器上向用户显示响应文本,而不是在处理完cURL请求后转发用户。如果此结果包含您不需要的大量垃圾,请考虑使用DOMDocument::loadHTML或第三方库(例如Masterminds/html5-phpPHPPowertools/DOM-Query)解析结果。

您也可以编写自己的自定义回复文字。

答案 1 :(得分:3)

简短回答:

  • POST到外部服务器
  • 解析回复
  • 不要回复任何事情
  • 使用标题(&#39;位置:url?param = res&#39;);
  • 退出; //这有点重要
  

我不希望在我的PHP脚本中收到POST请求的结果,而只是想将用户发送到他们看到POST结果的外部站点

如果您要从PHP脚本发送POST请求,则响应将始终返回到相同的PHP脚本。我认为您想要的不是将响应发送回用户,而是将用户重定向到另一个URL。为此你确定你正在做。

header('Location: url?param=res') ;
exit ;

并且在header()调用之前没有向客户端发送任何内容

答案 2 :(得分:3)

您只能在表单提交时发布值

action = "path/filename.php";

在此表单中,您可以发布表单值。

如果您想在能够通过URL

传递值时重定向文件
header('Location: url/filename.php?param1=      ');

尝试使用您要发布的本地文件值。

首先,您需要从表单中分配值,然后使用变量重定位标头。这可能是我方面的正确解决方案。  谢谢。

答案 3 :(得分:3)

我有一个适合您的解决方案,可以99%的时间或100%的时间工作,具体取决于您的实施方式。您需要做的就是使用AJAX处理表单。我知道你想要一个免费的Javascript方式,但这是最简单的方法。如果您使用jQuery库,文档和SO答案很容易理解,您不必编写很多代码。只需修改一些。这是概念:

1)页面正常加载,表单操作指向付款处理网站。由于您使用Javascript(jQuery)提交表单,您将替换提交按钮html,如下所示:

<input type="button" value="Check Out" onclick="NameofAjaxFunctionHere();"

2)交换表单操作值。在将要在后台发送表单的实际AJAX代码之前,使用与此代码类似的内容将操作更改为您自己的PHP页面:

 $('#formIdHere').attr('action', 'yourPHPpageAndPathHere.php');

此代码适用于jQuery,但如果需要,应该很容易更改为纯JavaScript。现在还要确保您的AJAX代码不会重置表单。许多复制和过去的代码都会为您做到这一点。

3)(可选)在此阶段,表单已发送到您的PHP页面,您已完成所需的操作。您现在有两个选择:

  • 不要等待回复,只是继续回到第4位。
  • 等待响应并做出相应的反应+如果需要更改数据

如果您需要确保数据正确或需要更改其中一些数据,请立即执行此操作。如果表单数据失败,您的进程(例如更改的数据)将返回FALSE并转到数字4.如果您需要更改这是一个简单的过程。发回需要在数组中更新的所有数据,并在启动此过程的相同AJAX代码中循环遍历它。使用Javascript,您可以更改表单值。

[Code missing because I think you can figure this out if you need to do that. If not comment and when I have time I will post an example]

4)交换表单操作。您的AJAX处理已完成。传统上它擦除表单并显示消息。如果您从上面选择发送FALSE以停止提交以防万一有错误数据的选项,那么现在只需从AJAX脚本返回false(可能会在返回之前显示一些内容,表示未发送表单)。

 $('#formIdHere').attr('action', 'paymentUrlHere');

现在支付网址已经恢复到位,如果您需要更新所有数据,请按照正常情况(或将来)提交表单。在jQuery中,这可以很简单:

 $('#formIdHere').submit();

我认为这涵盖了它。此时,用户不在您的手中,并通过正常的POST发送到付款处理网站。如果需要,您甚至有机会从表单中更改数据。

OH PS - 这就是我在本文开头的99%和100%方式的含义。 100%是我在这里给你的例子。没有人可以先发送表单而不将其发送到您自己的PHP页面。 99%的解决方案是,但正常提交页面中的html如下:

<input type="submit" ...>

然后使用Javascript停止默认提交操作并按照我的步骤1-4进行操作。这样,如果有人禁用javascript(或在阻止它的设备上),表单仍然至少发送给支付处理器。取决于你想要做什么。

答案 4 :(得分:1)

它是不可能的,完全加载页面,有机会使用POST请求空数据,而不是在需要时使用此创建会话,并且在使用该会话后只是销毁会话。 第二个是使用CURL。

答案 5 :(得分:1)

你的描述中有很好的计划。为什么您在格式化后不会在页面2上生成带有编辑数据的3页的http://github.com/dart-lang/sdk/issues/new请求?您可以使用Chrome扩展程序new POST

测试新的POST请求

答案 6 :(得分:1)

使用PHP是不可能的。

但您可以使用此调整,在 http://example.com/script.php 中,您可以使用校验和编写一些javascript自动提交代码。例如。

<body onload="document.frm1.submit()">   
<form method="POST" action="https://gatewaysite.com" name="frm1">
  <input name="checksum" value="yourchecksumvalue" />
  <input name="variable2" />
</form>
</body>

答案 7 :(得分:0)

如果您是这两个网站的所有者,那么您可以在每个.htacess文件中包含这些网站,这些网站将保持加密状态。

这两个站点上的SSL CA的资格。

在您的.htaccess中,您可以通过以下方式执行此操作: 这在网站#1的htaccess中添加了:

     RewriteCond %{HTTP_REFERER} !^https://www.site2.com/.*$      [NC]
     RewriteCond %{HTTP_REFERER} !^https://www.site2.com$      [NC]

这在网站#2的htaccess中添加了:

     RewriteCond %{HTTP_REFERER} !^https://www.site1.com/.*$      [NC]
     RewriteCond %{HTTP_REFERER} !^https://www.site1.com$      [NC]

然后您可以在网站#1上使用标准的html表单,如:

       <form action="https://wwww.site2.com" method="POST">

答案 8 :(得分:0)

在这种情况下可以使用AJAX。

mysite.com/pay上的表单指向gatewaysite。 在提交时,您运行一个将调用script.php的函数。 仅当script.php确认数据正确时,才会提交表单。