带有 Post 参数的 PHP 重定向

IT技术 php javascript post redirect parameters
2021-02-12 03:08:21

我有一个网页。该网页或多或少通过以下方式将用户重定向到另一个网页:

<form method="post" action="anotherpage.php" id="myform">

    <?php foreach($_GET as $key => $value){
    echo "<input type='hidden' name='{$key}' value='{$value}' />";
    } ?>

</form>
<script>

    document.getElementById('myform').submit();

</script>

好吧,你看,我所做的是将 GET 参数转换为 POST 参数。不要告诉我它不好,我自己知道,这并不是我真正做的事情,重要的是我从数组中收集数据并尝试通过 POST 将其提交到另一个页面。但是如果用户关闭了 JavaScript,它将无法工作。我需要知道的是:有没有办法通过 PHP 传输 POST 参数,以便重定向也可以通过 PHP 方式 ( header('Location: anotherpage.php');)完成

通过 POST 传递参数对我来说非常重要。我无法使用 $_SESSION 变量,因为该网页位于另一个域中,因此 $_SESSION 变量不同。

无论如何,我只需要一种使用 PHP 传输 POST 变量的方法 ^^

提前致谢!

6个回答

您可以通过标头重定向 POST 请求,并包含 POST 信息。但是,您需要显式返回 HTTP 状态代码 307。浏览器将 302 视为使用 GET 重定向,忽略原始方法。这在 HTTP 文档中明确指出:

实际上,这意味着在 PHP 中您需要在重定向位置之前设置状态代码:

    header('HTTP/1.1 307 Temporary Redirect');
    header('Location: anotherpage.php');

但是,请注意,根据 HTTP 规范,用户代理必须询问用户是否可以将 POST 信息重新提交到新 URL。实际上,Chrome 不会询问,Safari 也不会询问,但 Firefox 会向用户显示一个确认重定向的弹出框。根据您的操作限制,也许这没问题,但在一般使用情况下,它肯定有可能给最终用户造成混淆。

无法直接从服务器执行此操作,因为 POST 数据应由浏览器发送。

但是你可以选择一个替代方案:

  • 在您的示例中自动提交的预填表单可以工作,但正如您所写的那样,这不是一个很好的做法,可能会让用户停留在空白页面上
  • 接收 GET 参数并使用 curl(或任何像样的 HTTP 客户端)将它们 POST 到第二个站点,然后将结果传输到浏览器。这称为代理,恕我直言,这可能是一个很好的解决方案。
  • 跨域进行会话共享,这在所有设置中都是不可能的,并且可能很复杂。设置完成后,会话共享对 PHP 代码几乎是透明的。如果您对 2 个域之间的通信有不止一种需求,那么这样做是值得的。

curl 解决方案示例,在域 1 上运行的代码:

//retrieve GET parameters as a string like arg1=0&arg1=56&argn=zz
$data = $_SERVER['QUERY_STRING']; 

// Create a curl handle to domain 2
$ch = curl_init('http://www.domain2.com/target_script.php'); 

//configure a POST request with some options
curl_setopt($ch, CURLOPT_POST, true);
//put data to send
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);    
//this option avoid retrieving HTTP response headers in answer
curl_setopt($ch, CURLOPT_HEADER, 0);
//we want to get result as a string
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
//if servers support is and you want result faster, allow compressed response
curl_setopt($ch, CURLOPT_ENCODING, 'gzip,deflate'); 

//execute request
$result = curl_exec($ch);

//show response form domain 2 to client if needed
echo $result;

就是这样,您客户端的浏览器甚至不会看到域 2 服务器,它只会从中获得结果。知道是否要将客户端重定向到域,请使用经典的 HTTP 标头进行。

header('Location: http://www.domain2.com');

当然,这是带有硬编码值的演示代码,还有两点留给您:

  • 安全性:应该过滤或重新创建查询字符串以仅传输需要的参数,并且您应该断言域 2 上的服务器返回 200 HTTP 代码。
  • 应用程序逻辑在这部分应该需要一些调整:如果域 2 应用程序希望在访问者到来的同一请求中获取发布数据,它不会这样做。从域 2 的角度来看,执行 POST 请求的客户端将是托管域 1 的服务器而不是客户端浏览器,如果客户端 IP 问题或其他客户端检查在域 2 上完成,这一点很重要。如果 POST 请求用于显示客户端特定的内容,您还必须进行一些服务器端跟踪,以将先前发布的数据与被重定向的访问者结合起来。
我想补充的一个方面(10 年后)是,如果浏览器通过 POST 发起请求,并且服务器想要重定向,但维护该方法,它可以在位置标头旁边发送 HTTP 状态代码 307,提示浏览器使用 POST 重新提交相同的数据。
2021-03-26 03:08:21
你这样说:“接收 GET 参数并使用 curl(或任何像样的 http 客户端)将它们发布到第二个站点,然后将结果传输到浏览器。这被称为代理,恕我直言,这可能是一个很好的解决方案。” 那么,我怎样才能将结果传输到浏览器呢?我已经在使用 curl,但我很难重定向。提前致谢!
2021-03-27 03:08:21
这不是真正的重定向,它更多的是使用 POST 方法将浏览器的初始 GET 请求转发到第二个服务器,然后从第二个服务器获取输出并将其返回给浏览器,例如使用 echo。我将用代码更新我的答案以向您展示
2021-04-01 03:08:21

可以像下面这样一起破解一些东西......(我并不是说你应该这样做!):

$res = "<form action='/path/to/new/page' method='POST' id='redirectHack'>
            <input type='hidden' id='postVar1' name='postVar1' value='12345'>
            <input type='hidden' id='postVar2' name='postVar2' value='67890'>
        </form>
        <script>
            document.getElementById('redirectHack').submit()
        </script>";
die($res);
这是一个有点非学术性的编码,但效果很好。谢谢你。
2021-03-27 03:08:21

将您的数据存储在会话中,然后使用 GET。

不幸的是,他说他不能使用域问题的会话 b/c。
2021-03-16 03:08:21
他可以将会话信息存储在共享数据库中并通过 GET 传递会话 ID。
2021-03-21 03:08:21
我对会话不是很有经验,但是:你的意思是我可以通过知道它的会话 ID 来访问存储在浏览器中的其他一些会话?
2021-03-21 03:08:21
@arik 浏览器不存储会话。所以,没有什么可以访问的。您可以通过提出不是“这实际上不是我所做的,也不是我运行的实际代码”形式的问题来极大地帮助自己由于缺乏经验,最好的提问方式就是问真实的问题。
2021-04-10 03:08:21

不。您不能使用 POST 进行标头重定向。你有2个选择,

  1. 如果目标接受 POST 或 GET,您可以改用 GET。
  2. 我们会在 Javascript 关闭的极少数情况下添加一个按钮。

这是一个例子,

<noscript>
<div>
<input type="submit" value="Continue"/>
</div>
</noscript>

如果 Javascript 关闭,这将显示一个继续按钮,以便用户可以单击继续。