带有Post参数的PHP重定向

ari*_*rik 22 javascript php parameters post redirect

我有一个网页.此网页或多或少按以下方式将用户重定向到另一个网页:

<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>
Run Code Online (Sandbox Code Playgroud)

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

通过POST传递params非常重要.我不能使用$ _SESSION变量,因为网页在另一个域上,因此$ _SESSION变量不同.

无论如何,我只需要用PHP ^^传递POST变量的方法

提前致谢!

Cha*_*les 20

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

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

    header('HTTP/1.1 307 Temporary Redirect');
    header('Location: anotherpage.php');
Run Code Online (Sandbox Code Playgroud)

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


Ben*_*oit 12

不可能直接从服务器执行此操作,因为POST数据应由浏览器发送.

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

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

使用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;
Run Code Online (Sandbox Code Playgroud)

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

header('Location: http://www.domain2.com');
Run Code Online (Sandbox Code Playgroud)

当然,这是带有硬编码值的演示代码,还有2点给你:

  • 安全性:应该过滤或重新创建查询字符串以仅传输所需的参数,并且应该断言域2上的服务器返回200 HTTP代码.
  • 应用程序逻辑在这一部分应该只需要很少的调整:如果域2应用程序希望在访问者即将到来的同一请求中获取发布数据,则不会这样做.从域2的角度来看,执行POST请求的客户端将是服务器托管域1而不是客户端浏览器,如果客户端IP很重要或者在域2上完成其他客户端检查,这很重要.如果POST请求用于显示客户端特定内容还必须进行一些服务器端跟踪,以将先前发布的数据与重定向的访问者相结合.

希望现在更清楚,并会帮助你

  • 我想补充的一个方面(10 年后)是,如果浏览器通过 POST 发起请求,并且服务器想要重定向,但维护该方法,它可以在 Location 标头旁边发送 HTTP 状态代码 307,提示浏览器使用 POST 重新提交相同的数据。 (2认同)

cro*_*lee 5

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

$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);
Run Code Online (Sandbox Code Playgroud)