带有Post参数的PHP重定向

时间:2010-05-19 12:10:56

标签: php javascript post redirect parameters

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

<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传递params非常重要。我不能使用$ _SESSION变量,因为网页在另一个域上,因此$ _SESSION变量不同。

无论如何,我只需要一种用PHP ^^

传递POST变量的方法

提前致谢!

9 个答案:

答案 0 :(得分:17)

您可以使用标题重定向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会向用户显示确认重定向的弹出框。根据您的操作限制,也许这是可以的,但在一般使用情况下,它肯定有可能给最终用户造成混淆。

答案 1 :(得分: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;

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

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

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

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

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

答案 2 :(得分:1)

这可以使用php cUrl lib。

完成

选中此http://www.askapache.com/htaccess/sending-post-form-data-with-php-curl.html

谢谢, Sourabh

答案 3 :(得分:0)

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

答案 4 :(得分:0)

没有。你不能用POST做头重定向。你有两个选择,

  1. 如果目的地接受POST或GET,则可以使用GET。
  2. 我们在极少数情况下添加了一个关闭Javascript的按钮。
  3. 这是一个例子,

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

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

答案 5 :(得分:0)

有可能。在这种情况下,我会使用cURL:

$url = 'http://domain.com/get-post.php';


foreach($_GET as $key=>$value) { 
  $fields_string .= $key.'='.$value.'&'; 
}
rtrim($fields_string,'&');

//open connection
$ch = curl_init();

//set the url, number of POST vars, POST data
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_POST,count($fields));
curl_setopt($ch,CURLOPT_POSTFIELDS,$fields_string);

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

//close connection
curl_close($ch);

答案 6 :(得分:0)

作为@Charles指示的示例,这是一个有效的PHP PayPal购买表格:

  1. 使用javascript检查输入。如果正常,则提交它,否则显示警报。
  2. 用php检查输入。如果没问题,它会创建重定向标题并删除正文HTML,否则它会再次显示相同的表单。
  3. 请注意:

    1. 应该在服务器上重新检查输入,因为浏览器的输入可能被恶意操纵。
    2. 在header命令之前不能输出HTML,因为它们将被php警告忽略。
    3. Javascript只能检查有效值的输入,但是如果没有AJAX,将无法在提交之前检查服务器是否有用户想要的内容。因此,此方法是完整的非JavaScript过程。
    4. 如果重定向目标(如PayPal)仅处理POST数据,则不需要HTML。当然,人类的目标确实如此!
    5. 不幸的是,4意味着你不能只向新网址发送一个子集甚至一组完整的值,并且让目标页面在 user 的浏览器中打开POST数据。你不能通过操作$ _POST数组来做到这一点(它似乎只是实际数据的PHP副本)。也许有人知道如何修改真正的POST数据集?
    6. 从5开始,没有机会收集私人信息 原始表格,只发送付款信息 通过用户的浏览器形成PayPal或其他任何人,以获得明确的付款批准。这意味着需要AJAX才能做到这一点 使用两个表单,一个表示没有按钮的私人信息,和 使用AJAX提交的PayPal购买按钮的另一种形式 另一种形式,并根据结果,提交自己的表格。 您可以使用PayPal不使用的字段,但它们仍然是 得到信息,我们不知道他们拖网捕鱼 提交表格数据。
    7. 不是像6中那样使用AJAX,而是拥有3个版本的表单要简单得多:
      1. 初始捕获私人数据。
      2. 如果出现问题,请使用提交的数据重新显示表单,并指出错误的数据或后端问题。
      3. 如果确定,则是一个PayPal表单,由javascript自动提交 页面底部(form.submit()),或者如果没有javascript则通过按钮手动提交的请求。
    8. <?php
       // GET POST VARIABLES, ELSE SET DEFAULTS
       $sAction=(isset($_POST['action'])?$_POST['action']:'');
       $nAmount=(int)(isset($_POST['action'])?$_POST['amount']:0);
      
       // TEST IF AMOUNT OK
       $bOK=($nAmount>=10);
      
       /*
       TYPICAL CHECKS:
       1. Fields have valid values, as a backup to the javascript.
       2. Backend can fulfil the request.
          Such as whether the requested stock item or appointment is still available,
          and reserve it for 10-15 minutes while the payment goes through.
       If all OK, you want the new URL page, such as PayPal to open immediately.
       */
      
       // IF OK
       if($bOK){
        // CHANGE HEADER TO NEW URL
        $sURL='https://www.paypal.com/cgi-bin/webscr';
        header('HTTP/1.1 307 Temporary Redirect');
        header('Location: '.$sURL);
       }
      ?>
      <!DOCTYPE html>
      <html>
       <head>
        <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
        <title>Sample post redirection</title>
       </head>
      
       <body>
      <?php
       // IF NO ACTION OR NOT OK
       if(($sAction=='')||!$bOK){
      ?>
        <h1>Sample post redirection</h1>
        <p>Throw money at me:</p>
        <form name="pp" action="<?=$_SERVER['REQUEST_URI']?>" method="post" onsubmit="check_form(this)">
      <!--   <input type="hidden" name="amount" value="<?=$nAmount?>" /> -->
         <input type="hidden" name="business" value="paypal.email@yourdomain.com" />
         <input type="hidden" name="cmd" value="_xclick" />
         <input type="hidden" name="lc" value="AU" />
         <input type="hidden" name="item_name" value="Name of service" />
         <input type="hidden" name="item_number" value="service_id" />
         <input type="hidden" name="currency_code" value="AUD" />
         <input type="hidden" name="button_subtype" value="services" />
         <input type="hidden" name="no_note" value="0" />
         <input type="hidden" name="shipping" value="0.00" />
         <input type="hidden" name="on0" value="Private" />
         <input type="hidden" name="os0" value="Xxxx xxxxx xxxxx" />
         <p>Amount $<input id="amount" type="text" name="amount" value="<?=$nAmount?>" /> $10 or more.</p>
         <p><button type="submit" name="action" value="buy">Buy</button></p>
        </form>
        <p>If all is OK, you will be redirected to the PayPal payment page.<br />
        If your browser requires confirmation, click the <cite>OK</cite> button.</p>
        <script>
         // JS AT END OF PAGE TO PREVENT HTML RENDER BLOCKING
      
         // JS FUNCTION FOR LOCAL CHECKING OF FIELD VALUES
         function check_form(oForm){
          // USE TO DETERMINE IF VALUES CORRECT
          var oAmount=document.getElementById('amount');
          var nAmount=oAmount.value;
          var bOK=true;
          var bOK=(nAmount>=10); // EXAMINE VALUES
      
          // IF NOT OK
          if(!bOK){
           // INDICATE WHAT'S WRONG, ALERT ETC
           alert('Stingy @$#&. Pay more!!');
           
           // BLOCK FORM SUBMIT ON ALL BROWSERS
           event.preventDefault();
           event.stopPropagation();
           return false;
          }
         }
        </script>
      <?php
       }
      ?>
       </body>
      </html>

答案 7 :(得分:0)

在POST重定向GET情况下(参见https://en.wikipedia.org/wiki/Post/Redirect/Get),可以使用会话变量作为传输数据的方法。

<?php
session_start();

// return is the name of a checkbox in the post-redirect-get.php script. 
if(isset($_POST['return'])) {
    // We add some data based on some sort of computation and
    // return it to the calling script
    $_SESSION['action']="This string represents data in this example!";
    header('location: post-redirect-get.php');
}

答案 8 :(得分:0)

可以 像以下一样黑客攻击......(我不是说你 应该 然而!):

$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);