2010-06-15 194 views
40

Tengo una puerta de enlace en línea que requiere que se envíe un formulario HTML con campos ocultos. Necesito hacer esto a través de un script PHP sin ningún tipo de formularios HTML (no tengo los datos para los campos ocultos en un DB)PHP - Redirigir y enviar datos a través de POST

Para hacer esto, el envío de datos a través de GET:

header('Location: http://www.provider.com/process.jsp?id=12345&name=John'); 

Y para hacer esto enviando datos a través de POST?

Respuesta

39

No se puede hacer esto usando PHP.

Como han dicho otros, podría usar cURL, pero luego el código PHP se convierte en el cliente en lugar del navegador.

Si debe usar POST, la única forma de hacerlo sería generar el formulario rellenado con PHP y usar el gancho window.onload para llamar a javascript y enviar el formulario.

C.

+3

Bueno, es raro que cURL no sea la solución, ya que yo mismo lo he usado para hacer exactamente esto. Pero supongo que tu solución también funciona. –

+0

Puede usar el método jQuery $ .post. En este caso, puede elegir entre opciones para permanecer en este sitio o redirigir cuando se envía. – Ervin

+0

Sí, es posible proxy la solicitud y convertirla en una POST usando PHP y curl, pero eso implica que el extremo receptor es susceptible a CSRF y/o no está aplicando controles basados ​​en la sesión sobre la solicitud (puede borrar algunos de esto, pero no todos en los parámetros pasados ​​a curl) – symcbean

1

Use curl para esto. Google para "curl php post" y encontrarás esto: http://www.askapache.com/htaccess/sending-post-form-data-with-php-curl.html.

Tenga en cuenta que también puede usar una matriz para la opción CURLOPT_POSTFIELDS. De php.net documentos:

Los datos completos se publicarán en una operación HTTP "POST". Para publicar un archivo, anteponga un nombre de archivo con @ y use la ruta completa. Esto se puede pasar como una cadena urlencoded como 'para1 = val1 & para2 = val2 & ...' o como una matriz con el nombre del campo como clave y datos de campo como valor. Si value es una matriz, el encabezado Content-Type se establecerá en multipart/form-data.

4

Implicaría la extensión cURL PHP.

$ch = curl_init('http://www.provider.com/process.jsp'); 
curl_setopt($ch, CURLOPT_POST, 1); 
curl_setopt($ch, CURLOPT_POSTFIELDS, "id=12345&name=John"); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER , 1); // RETURN THE CONTENTS OF THE CALL 
$resp = curl_exec($ch); 
+1

Hey Matt, Esto no es posible con CURL. Por curl no seremos redirigidos. – rahul

1

usted tiene que abrir un socket para el sitio con fsockopen y simular un HTTP-Post-Request. Google le mostrará muchos fragmentos de cómo simular la solicitud.

26

aquí está la solución alternativa.

function redirect_post($url, array $data) 
{ 
    ?> 
    <html xmlns="http://www.w3.org/1999/xhtml"> 
    <head> 
     <script type="text/javascript"> 
      function closethisasap() { 
       document.forms["redirectpost"].submit(); 
      } 
     </script> 
    </head> 
    <body onload="closethisasap();"> 
    <form name="redirectpost" method="post" action="<? echo $url; ?>"> 
     <?php 
     if (!is_null($data)) { 
      foreach ($data as $k => $v) { 
       echo '<input type="hidden" name="' . $k . '" value="' . $v . '"> '; 
      } 
     } 
     ?> 
    </form> 
    </body> 
    </html> 
    <?php 
    exit; 
} 
+1

¡Es una solución "sucia", pero definitivamente funciona! Hice una función similar pero con un 'eco' explícito en lugar de cerrar y volver a abrir las etiquetas' ' – DiegoDD

+0

Me encanta este tipo de cosas sucias. las etiquetas php pueden tener que establecerse como Kemal

+0

@DiegoDD: ¿tiene algún código/esencia para poder copiar? – Hiep

0

que utiliza el código siguiente para capturar los datos POST que se envían desde form.php y luego concatenarlo a una dirección URL para enviar de nuevo a la forma de correcciones de validación. Funciona como un amuleto y, de hecho, convierte datos POST en datos GET.

foreach($_POST as $key => $value) { 
    $urlArray[] = $key."=".$value; 
} 
$urlString = implode("&", $urlArray); 

echo "Please <a href='form.php?".$urlString."'>go back</a>"; 
+0

Desafortunadamente, esto no es lo que se preguntó. Quiere realizar una POST mediante una redirección, no convertir POST a GET. – TimWolla

+1

Además, si desea lograr esto, también puede usar la función nativa de PHP 'http_build_query()'. – Ben

2
/** 
* Redirect with POST data. 
* 
* @param string $url URL. 
* @param array $post_data POST data. Example: array('foo' => 'var', 'id' => 123) 
* @param array $headers Optional. Extra headers to send. 
*/ 
public function redirect_post($url, array $data, array $headers = null) { 
    $params = array(
     'http' => array(
      'method' => 'POST', 
      'content' => http_build_query($data) 
     ) 
    ); 
    if (!is_null($headers)) { 
     $params['http']['header'] = ''; 
     foreach ($headers as $k => $v) { 
      $params['http']['header'] .= "$k: $v\n"; 
     } 
    } 
    $ctx = stream_context_create($params); 
    $fp = @fopen($url, 'rb', false, $ctx); 
    if ($fp) { 
     echo @stream_get_contents($fp); 
     die(); 
    } else { 
     // Error 
     throw new Exception("Error loading '$url', $php_errormsg"); 
    } 
} 
+0

Soy nuevo en PHP.¿Hay alguna forma de cambiar la URL con ella? Esta función no cambia la URL, pero redirige. Estoy dejando '$ headers' como' null' (¿debería estarlo?). –

8

Otra solución si desea evitar una llamada rizo y tienen el redireccionamiento del navegador como normal e imitar una llamada POST:

guardar la publicación y hacer una redirección temporal:

function post_redirect($url) { 
    $_SESSION['post_data'] = $_POST; 
    header('Location: ' . $url); 
} 

a continuación, compruebe siempre que la variable de sesión post_data:

if (isset($_SESSION['post_data'])) { 
    $_POST = $_SESSION['post_data']; 
    $_SERVER['REQUEST_METHOD'] = 'POST'; 
    unset($_SESSION['post_data']); 
} 

Habrá algunos componentes que faltan, como los apache_request_headers() no se mostrará una cabecera Content POST, etc ..

+0

Gracias por la solución sucia más limpia. – Gregzenegair

1

Alternativamente, el establecimiento de una variable de sesión antes de la redirección y probarlo en la URL de destino, puede resolver este problema para mi

0

Sí, puedes hacerlo en PHP, p. Ej. en

Silex o Symfony3

usando subpetición

$postParams = array(
    'email' => $request->get('email'), 
    'agree_terms' => $request->get('agree_terms'), 
); 

$subRequest = Request::create('/register', 'POST', $postParams); 
return $app->handle($subRequest, HttpKernelInterface::SUB_REQUEST, false); 
0

una entrada antigua, pero aquí es cómo lo manejé. Utilizando el método de newms87:

if($action == "redemption") 
{ 
    if($redemptionId != "") 
    { 
     $results = json_decode($rewards->redeemPoints($redemptionId)); 

     if($results->success == true) 
     { 
      $redirectLocation = $GLOBALS['BASE_URL'] . 'rewards.phtml?a=redemptionComplete'; 
      // put results in session and redirect back to same page passing an action paraameter 
      $_SESSION['post_data'] = json_encode($results); 
      header("Location:" . $redirectLocation); 
      exit(); 
     } 
    } 
} 
elseif($action == "redemptionComplete") 
{ 
    // if data is in session pull it and unset it. 
    if(isset($_SESSION['post_data'])) 
    { 
     $results = json_decode($_SESSION['post_data']); 
     unset($_SESSION['post_data']); 
    } 
    // if you got here, you completed the redemption and reloaded the confirmation page. So redirect back to rewards.phtml page. 
    else 
    { 
     $redirectLocation = $GLOBALS['BASE_URL'] . 'rewards.phtml'; 
     header("Location:" . $redirectLocation); 
    } 
} 
0

Un wich solución funciona perfectamente:

En la página de origen ,, empezar a abrir una sesión y asignar tantos valores como es posible que desee. Después, realice el traslado de "cabecera":

<!DOCTYPE html> 
<html> 
    <head> 
     <?php 
      session_start(); 
      $_SESSION['val1'] = val1; 
      ... 
      $_SESSION['valn'] = valn; 
      header('Location: http//Page-to-redirect-to'); 
     ?> 
    </head> 
</html> 

Y luego, en la página Targe:

<!DOCTYPE html> 
<?php 
    session_start(); 
?> 
<html> 
    ... 
    <body> 
     <?php 
      if (isset($_SESSION['val1']) && ... && isset($_SESSION['valn'])) { 
       YOUR CODE HERE based on $_SESSION['val1']...$_SESSION['valn'] values 
      } 
     ?> 
    </body> 
</html> 

No hay necesidad de Javascript jQuery ni .. Buena suerte!

Cuestiones relacionadas