web-dev-qa-db-fra.com

PHP Redirection avec paramètres de post

J'ai une page web. Cette page Web redirige l'utilisateur vers une autre page Web, plus ou moins de la manière suivante:

<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>

Eh bien, voyez-vous, ce que je fais est de transférer les paramètres GET dans les paramètres POST. Ne me dites pas que c'est mauvais, je le sais moi-même, et ce n'est pas exactement ce que je fais vraiment, mais il est important que je collecte les données d'un tableau et que j'essaie de les soumettre à une autre page via POST. Mais si l'utilisateur a désactivé JavaScript, cela ne fonctionnera pas. Ce que je dois savoir: Y a-t-il un moyen de transférer les paramètres POST au moyen de PHP pour que la redirection puisse également s'effectuer de la manière PHP (header('Location: anotherpage.php');)?

Il est très important pour moi de passer les paramètres via POST. Je ne peux pas utiliser la variable $ _SESSION car la page Web se trouve sur un autre domaine. Les variables $ _SESSION sont donc différentes.

Quoi qu'il en soit, j'ai simplement besoin d'un moyen de transférer POST des variables avec PHP ^^

Merci d'avance!

21
arik

Aucune possibilité de le faire directement à partir du serveur, car POST les données doivent être envoyées par le navigateur. 

Mais vous pouvez choisir une alternative:

  • Le formulaire prérempli automatiquement soumis dans votre exemple pourrait fonctionner, mais comme vous l'avez écrit, ce n'est pas vraiment une bonne pratique et peut laisser les utilisateurs sur une page vierge.
  • Recevez des arguments GET et POST avec curl (ou tout client http décent) sur un deuxième site, puis transférez le résultat au navigateur. Cela s'appelle un proxy et peut être une bonne solution à mon humble avis.
  • Partage de session sur plusieurs domaines, cela ne peut pas être possible sur toutes les configurations et peut être complexe. Une fois la configuration terminée, le partage de session est presque transparent pour le code php. Si vous avez plusieurs besoins de communication entre les 2 domaines, cela peut valoir la peine de le faire.

Exemple avec la solution curl, code à exécuter sur le domaine 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;

Ça y est, le navigateur de votre client ne verra même pas le serveur de domaine 2, il obtiendra uniquement le résultat. Si vous voulez rediriger le client vers le domaine, faites-le avec un en-tête http classique.

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

Bien sûr, il s’agit d’un code de démonstration avec des valeurs codées en dur, et il vous reste 2 points: 

  • Sécurité: la chaîne de requête doit être filtrée ou recréée pour ne transmettre que les paramètres nécessaires, et vous devez affirmer que le serveur du domaine 2 a renvoyé un code 200 HTTP.
  • La logique de l'application devrait nécessiter peu d'ajustement sur cette partie: si l'application du domaine 2 s'attend à obtenir des données de publication dans la même demande que le visiteur arrive, elle ne le fera pas. Du point de vue du domaine 2, le client faisant POST la demande sera le domaine d'hébergement du serveur 1 et non le navigateur client, il est donc important que l'IP du client soit important ou que d'autres vérifications soient effectuées sur le domaine 2 POST La requête sert à afficher le contenu spécifique au client. Vous devez également effectuer un suivi côté serveur afin de combiner les données précédemment publiées avec le visiteur redirigé.

J'espère que c'est plus clair maintenant et que cela vous aidera

12
Benoit

Vous pouvez en-tête CAN rediriger une demande POST et inclure les informations POST. Toutefois, vous devez explicitement renvoyer le code d'état HTTP 307. Les navigateurs traitent 302 comme une redirection avec pour GET, en ignorant la méthode d'origine. Ceci est noté explicitement dans la documentation HTTP:

En pratique, cela signifie que dans PHP vous devez définir le code de statut avant l'emplacement de redirection:

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

Cependant, notez que, conformément à la spécification HTTP, l'agent utilisateur DOIT demander à l'utilisateur s'il est en mesure de soumettre à nouveau les informations POST à la nouvelle URL. Concrètement, Chrome ne pose pas de question, pas plus que Safari, mais Firefox présentera à l'utilisateur une boîte de dialogue contextuelle confirmant la redirection. En fonction de vos contraintes d’exploitation, c’est peut-être correct, bien que dans un cas d’utilisation général, il risque de créer de la confusion chez les utilisateurs finaux.

16
Charles

Cela peut être fait en utilisant php cUrl lib.

Vérifiez ceci http://www.askapache.com/htaccess/sending-post-form-data-with-php-curl.html

Merci, Sourabh

1
Sourabh

C'est possible. Dans cette situation, j'utiliserais 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

Dans une POST redirection d'une situation GET, (voir https://en.wikipedia.org/wiki/Post/Redirect/Get ), il est acceptable d'utiliser la variable de session comme méthode de transport les données.

<?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

Non, vous ne pouvez pas faire de redirection d'en-tête avec POST. Vous avez 2 options,

  1. Vous pouvez utiliser GET à la place si la destination accepte POST ou GET.
  2. Nous ajoutons un bouton dans de rares cas où le Javascript est désactivé.

Voici un exemple,

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

Ceci affichera un bouton Continuer si Javascript est désactivé afin que l'utilisateur puisse cliquer pour continuer.

0
ZZ Coder

Vouspourriezpirater quelque chose comme ceci ... (je ne vous dis pasdevraitcependant!)

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

Stockez vos données dans une session, puis utilisez GET.

0
ThiefMaster

À titre d'exemple de ce que @Charles indique, voici un formulaire d'achat Paypal en PHP qui fonctionne:

  1. Vérifie l'entrée avec javascript. Si OK, il le soumet, sinon affiche une alerte.
  2. Vérifie l'entrée avec php. Si OK, il crée les en-têtes de redirection et supprime le corps HTML, sinon il affiche à nouveau le même formulaire.

Notez que:

  1. Les entrées doivent être revérifiées sur le serveur, car les entrées d'un navigateur peuvent être manipulées de manière néfaste.
  2. Aucun code HTML ne peut être généré avant les commandes d'en-tête, car elles seront ignorées avec un avertissement php.
  3. Javascript ne peut rechercher que des valeurs valides dans les entrées, mais sans AJAX, il ne sera pas en mesure de vérifier le serveur pour ce que l'utilisateur souhaite avant la soumission. Par conséquent, cette méthode est le processus complet non javascript.
  4. Aucun code HTML n'est requis si la cible de la redirection (telle que Paypal) traite uniquement les données POST. Les cibles pour les humains, bien sûr!
  5. Malheureusement, 4 signifie que vous ne pouvez pas envoyer uniquement un sous-ensemble ou même un ensemble complet de valeurs à la nouvelle URL, ET que la page cible qui traite les données POST soit ouverte dans le navigateur de user. Vous ne pouvez pas faire cela en manipulant le tableau $ _POST (il ne semble s'agir que d'une copie PHP des données réelles). Peut-être que quelqu'un sait comment modifier le jeu de données réel POST?
  6. À partir de 5, il n’est plus possible de collecter des informations privées sur le formulaire original Il suffit d’envoyer les informations de paiement figurant sur le formulaire À Paypal ou à un autre utilisateur, via le navigateur de l’utilisateur, pour approbation de leur paiement. Cela signifie que AJAX est nécessaire pour le faire en En utilisant deux formulaires, l'un contenant les informations privées sans bouton, et l'autre formulaire avec le bouton d'achat Paypal qui utilise AJAX pour envoyer l'autre formulaire, et en fonction du résultat, soumettez son propre formulaire . Vous pouvez utiliser des champs que Paypal n'utilise pas, mais ils sont toujours obtenir les informations, et nous ne savons pas quoi ils ont chaluté sur données du formulaire soumis.
  7. Plutôt que d’utiliser AJAX comme dans 6, il serait beaucoup plus simple d’avoir 3 versions du formulaire:
    1. Initial pour capturer les données privées.
    2. En cas de problème, réafficher le formulaire avec les données soumises et indiquer les données incorrectes ou le problème lié au backend.
    3. Si OK, un formulaire Paypal, soumis automatiquement par javascript à Au bas de la page (form.submit ()), ou une demande de soumission manuelle par un bouton si pas de 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