web-dev-qa-db-ja.com

PHP Postパラメータによるリダイレクト

私はウェブページを持っています。このWebページは、ユーザーを別のWebページにリダイレクトします。

_<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 paramsに転送しています。それは悪いことだと言わないでください。自分自身が実際に行っていることとは異なります。重要なのは、配列からデータを収集し、POSTを介して別のページに送信しようとすることです。ただし、ユーザーがJavaScriptをオフにしている場合は機能しません。知っておくべきこと:転送する方法はありますPOSTパラメータによるPHPリダイレクトを実行できるようにするためPHP方法(header('Location: anotherpage.php');)も) ?

POST経由でパラメーターを渡すことは非常に重要です。 $ _SESSION変数は使用できません。Webページが別のドメインにあるため、$ _ SESSION変数が異なるためです。

とにかく、POST PHP ^

前もって感謝します!

24
arik

POSTデータはブラウザから送信される必要があるため、サーバーから直接これを行うことはできません。

ただし、別の方法を選択できます。

  • 事前入力されたフォームが自動的に送信されたiniの例は機能しますが、あなたが書いたようにそれは実際には良い習慣ではなく、空白のページにユーザーを残すことができます
  • GET引数を受け取り、POST curl(または適切なhttpクライアント)でそれらを2番目のサイトに転送し、結果をブラウザーに転送します。これはプロキシーと呼ばれ、優れた解決策になる可能性があります。
  • ドメイン間でセッションを共有します。これはすべてのセットアップで可能であるわけではなく、複雑になる可能性があります。セットアップが完了すると、セッション共有は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ポイントです。

  • セキュリティ:クエリ文字列をフィルタリングまたは再作成して、必要なパラメーターのみを送信し、ドメイン2のサーバーが200 HTTPコードを返すことをアサートする必要があります。
  • アプリケーションロジックは、この部分で少し調整する必要があります。ドメイン2アプリが、訪問者が来ているのと同じリクエストで投稿データを取得することを期待している場合、それは行いません。ドメイン2の観点から見ると、POSTリクエストを実行するクライアントはサーバー1をホストするサーバーであり、クライアントブラウザーではありません。ドメイン2でクライアントIPが重要か他のクライアントチェックが行われるかどうかが重要です。 POSTリクエストは、以前に投稿されたデータをリダイレクトされる訪問者と組み合わせるためにサーバー側の追跡も行う必要があったクライアント固有のコンテンツを表示するために役立ちます。

それが今より明確になり、あなたを助けることを願っています

12
Benoit

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はリダイレクトを確認するポップアップボックスをユーザーに表示します。運用上の制約によっては、これは問題ないかもしれませんが、一般的な使用例では、エンドユーザーを混乱させる可能性があります。

24
Charles

あなたcould次のようにハッキングする...(私はあなたに言っているわけではありませんすべきであるしかし!):

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

これは、php cUrl libを使用して行うことができます。

これをチェックしてください http://www.askapache.com/htaccess/sending-post-form-data-with-php-curl.html

ありがとう、Sourabh

2
Sourabh

可能です。この状況では、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);
0
DBruns

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');
}
0
Joseph Pesco

いいえ。POSTでヘッダーリダイレクトを行うことはできません。 2つのオプションがあります。

  1. 宛先がPOSTまたはGETのいずれかを受け入れる場合は、代わりにGETを使用できます。
  2. Javascriptがオフになっているまれなケースでボタンを追加します。

ここに例があります

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

ユーザーがクリックして続行できるように、JavaScriptがオフの場合は、続行ボタンが表示されます。

0
ZZ Coder

セッションにデータを保存してから、GETを使用します。

0
ThiefMaster

@Charlesが示す内容のサンプルとして、次のような動作するphp Paypal購入フォームがあります。

  1. JavaScriptで入力をチェックします。 OKの場合は送信し、それ以外の場合はアラートを表示します。
  2. PHPで入力をチェックします。 OKの場合、リダイレクトヘッダーを作成し、本文のHTMLを削除します。それ以外の場合は、同じフォームを再度表示します。

ご了承ください:

  1. ブラウザの入力は不正に操作される可能性があるため、サーバーで入力を再確認する必要があります。
  2. Php警告で無視されるため、ヘッダーコマンドの前にHTMLを出力することはできません。
  3. JavaScriptは有効な値の入力のみをチェックできますが、AJAXがないと、ユーザーが送信する前にユーザーが何を望んでいるかサーバーをチェックできません。したがって、このメソッドは完全な非JavaScriptプロセスです。
  4. リダイレクトターゲット(Paypalなど)がPOSTデータのみを処理している場合、HTMLは必要ありません。もちろん、人間の標的もそうです!
  5. 残念ながら、4は、サブセットだけ、または他の完全な値のセットさえも新しいURLに送信できず、ターゲットページでPOSTデータを処理してserを開くことを意味しますブラウザ。 $ _POST配列を操作してこれを行うことはできません(実際のデータのPHPコピーにすぎないようです)。たぶん、誰かが実際のPOSTデータセットを変更する方法を知っていますか?
  6. 5からは、元のフォームの個人情報を収集する機会はなく、ユーザーのブラウザーを介して、フォームの支払い情報のみをPaypalまたは誰にでも送信して、明示的な支払い承認を得ることができます。つまり、AJAXは2つのフォームを使用してそれを行うために必要です。1つはボタンなしのプライベート情報を保持し、もう1つはAJAXを使用して他のフォームを送信するPaypal購入ボタンを使用します。結果が出たら、独自のフォームを送信します。 Paypalが使用しないフィールドを使用することもできますが、それらのフィールドはまだ情報を取得しており、送信されたフォームデータを何がトロールしているかはわかりません。
  7. 6のようにAJAXを使用するよりも、3つのバージョンのフォームを使用する方がはるかに簡単です。
    1. 個人データをキャプチャするための初期。
    2. 問題がある場合は、送信されたデータと不正確なデータまたはバックエンドの問題を示してフォームを再表示します。
    3. OKの場合、ページの下部にあるJavaScriptによって自動的に送信されたPaypalフォーム(form.submit())、またはJavaScriptがない場合はボタンによって手動で送信する要求。
<?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="[email protected]" />
   <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>
0
Patanjali