POST डेटा के साथ PHP रीडायरेक्ट


241

मैंने इस विषय पर कुछ शोध किया, और कुछ विशेषज्ञ हैं जिन्होंने कहा है कि यह संभव नहीं है , इसलिए मैं एक वैकल्पिक समाधान के लिए पूछना चाहूंगा।

मेरी स्थिति:

पृष्ठ A: [checkout.php] ग्राहक अपने बिलिंग विवरण में भरता है।

पृष्ठ B: [process.php] एक इनवॉइस नंबर बनाएं और ग्राहक के विवरण को डेटाबेस में संग्रहीत करें।

पृष्ठ C: [thirdparty.com] तीसरा भुगतान गेटवे (केवल ACCEPT POST DATA)।

ग्राहक अपने विवरणों को भरता है और पेज ए में अपनी कार्ट सेट करता है, फिर पेज बी के अंदर पोस्ट करता है। प्रक्रिया के दौरान, डेटाबेस के अंदर पोस्ट किए गए डेटा को संग्रहीत करता है और एक चालान नंबर उत्पन्न करता है। उसके बाद, ग्राहक के डेटा को पोस्ट करें और तीसरे नंबर के भुगतान नंबर पर जाएं। समस्या पेज बी में POST कर रही है। CURL पृष्ठ C पर डेटा को पोस्ट करने में सक्षम है, लेकिन समस्या पृष्ठ सी पर पुनर्निर्देशित नहीं है। ग्राहक को पृष्ठ C पर क्रेडिट कार्ड विवरण भरने की आवश्यकता है।

तीसरे पक्ष के भुगतान गेटवे ने हमें एपीआई नमूना दिया, नमूना ग्राहक विवरण के साथ एक साथ चालान संख्या है। हम नहीं चाहते कि सिस्टम अनचाहे इनवॉइस नंबरों की अधिकता उत्पन्न करे।

क्या इसका कोई समाधान है? हमारा वर्तमान समाधान ग्राहक के लिए पेज ए में विवरण भरने के लिए है, फिर पेज बी में हम ग्राहक के सभी विवरणों को दिखाते हुए एक और पेज बनाते हैं, जहां उपयोगकर्ता POST से पेज सी के लिए एक CONFIRM बटन पर क्लिक कर सकते हैं।

हमारा लक्ष्य ग्राहकों के लिए केवल एक बार क्लिक करना है।

आशा है मेरा प्रश्न स्पष्ट है :)


मुझे नहीं लगता कि इसके लिए डुप्लिकेट है, ऐसा इसलिए है क्योंकि मेरा लक्ष्य एक PHP पृष्ठ के अंदर है, POST डेटा पास करें और इसे रीडायरेक्ट करें। मुझे नहीं लगता कि यह करना संभव है। बस इसके लिए किसी भी विकल्प के लिए विशेषज्ञ की तलाश करें
Shiro

ʜᴛᴛᴘ 308 पुनर्निर्देशन कोड?
user2284570

जवाबों:


212

पेज बी पर सभी आवश्यक डेटा और कार्रवाई के साथ पेज बी पर एक फॉर्म जेनरेट करें और इसे पेज लोड पर जावास्क्रिप्ट के साथ सबमिट करें। आपका डेटा उपयोगकर्ता को बहुत परेशानी के बिना पेज सी पर भेजा जाएगा।

इसे करने का एकमात्र तरीका है। एक रीडायरेक्ट 303 HTTP हैडर है जिसे आप http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html पर पढ़ सकते हैं , लेकिन मैं इसमें से कुछ उद्धरण दूंगा:

अनुरोध की प्रतिक्रिया एक अलग URI के तहत मिल सकती है और उस संसाधन पर GET विधि का उपयोग करके पुनर्प्राप्त किया जा सकता है। यह विधि मुख्य रूप से एक चयनित संसाधन के लिए उपयोगकर्ता एजेंट को पुनर्निर्देशित करने के लिए POST- सक्रिय स्क्रिप्ट के आउटपुट की अनुमति देने के लिए मौजूद है। नया यूआरआई मूल रूप से अनुरोधित संसाधन के लिए एक स्थानापन्न संदर्भ नहीं है। 303 प्रतिसाद को कैश नहीं किया जाना चाहिए, लेकिन दूसरे (पुनर्निर्देशित) अनुरोध के प्रतिसाद अस्वीकार्य हो सकता है।

आप जो कर रहे हैं, उसे प्राप्त करने का एकमात्र तरीका एक मध्यवर्ती पृष्ठ है जो उपयोगकर्ता को पेज सी पर भेजता है। यहां एक छोटा / सरल स्निपेट दिया गया है कि आप इसे कैसे प्राप्त कर सकते हैं:

<form id="myForm" action="Page_C.php" method="post">
<?php
    foreach ($_POST as $a => $b) {
        echo '<input type="hidden" name="'.htmlentities($a).'" value="'.htmlentities($b).'">';
    }
?>
</form>
<script type="text/javascript">
    document.getElementById('myForm').submit();
</script>

आपके पास जावास्क्रिप्ट टैग के अंदर एक सरल "पुष्टि" फ़ॉर्म भी होना चाहिए ताकि यह सुनिश्चित हो सके कि बिना जावास्क्रिप्ट के उपयोगकर्ता आपकी सेवा का उपयोग करने में सक्षम होंगे।


2
मेरा लक्ष्य पृष्ठ A -> पृष्ठ C में है, पृष्ठ B नियंत्रक (व्यवसाय तर्क) चालान संख्या उत्पन्न करता है। सिस्टम दृश्य से पृष्ठ A-> पृष्ठ B-> पृष्ठ C है, लेकिन उपयोगकर्ता दृश्य से पृष्ठ A-> पृष्ठ B होना चाहिए, उन्हें कभी भी पृष्ठ B मौजूद नहीं होना चाहिए।
शिरो

3
@Peeter: स्मार्ट सुझाव +1। एकमात्र मुद्दा यह है कि जब पृष्ठ सी पर उपयोगकर्ता बैक पुश बटन को पृष्ठ सी पर फिर से भेज दिया जाता है। इसके अलावा आप एनकोड करना भूल जाते हैं $aऔर $bउपयोग करके htmlentities/htmlspecialchars, stackoverflow.com/questions/6180072/php-forward-data-post-…
Marco Demaio देखें

8
यहाँ सवाल है कि क्या जावास्क्रिप्ट क्लाइंट पर अक्षम है? पृष्ठ B, पृष्ठ C पर पुनर्निर्देशित नहीं करेगा, तो क्या यह होगा?
इमरान उमर बुकश

24
<noscript><input type="submit" value="Click here if you are not redirected."/></noscript>अंदर<form>
nullability

3
languageविशेषता हटाई गई है, यह होना चाहिए<script type="text/javascript">...</script>
एलेक्स डब्ल्यू

34
/**
 * 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");
    }
}

17
हालांकि पहले तो यह स्वीकार किए गए उत्तर से बेहतर दिखता है, मैं ध्यान देता हूं कि यह आपूर्ति को पुनर्निर्देशित नहीं करता है $url- यह केवल पृष्ठ की सामग्री के साथ मौजूदा पृष्ठ की सामग्री को बदलता है $urlमहत्वपूर्ण रूप से , $urlपृष्ठ में php कोड का मूल्यांकन नहीं किया गया है।
iPadDeveloper2011

@ iPadDeveloper2011, URL में, आपके पास एक PHP कोड नहीं है! PHP कोड SERVER में निष्पादित होता है, क्लाइंट में नहीं।
एडुआर्डो क्युमो

1
redirect_post(), जो सर्वर साइड है, php कोड है, सर्वर के लिए एक अनुरोध भेजता है $url। यदि $urlकोई .phpपृष्ठ है, तो मैं ध्यान देता हूं कि php का मूल्यांकन नहीं किया गया है - html अभी भी php टैग के साथ लौटा है। क्या POST डेटा को सर्वर साइड स्क्रिप्ट पर भेजने की पूरी बात नहीं है?
iPadDeveloper2011

2
@EduardoCuomo केवल फोपेन () कैसे काम करता है, इस कारण से यह विधि केवल एब्सॉर्ल यूरल्स के साथ काम करती है: php.net/manual/en/function.fopen.php यह अभी भी एक बहुत अच्छा जवाब है।
ओमनी

@ आप सही हैं! "यह सापेक्ष URL के साथ काम नहीं करता है?" एक सवाल नहीं है, एक बयान है। भ्रम के लिए क्षमा करें
एडुआर्डो क्युमो

25

मेरे पास एक और उपाय है जो इसे संभव बनाता है। इसके लिए क्लाइंट को जावास्क्रिप्ट (जो मुझे लगता है कि इन दिनों एक उचित आवश्यकता है) चल रहा है।

बस पृष्ठभूमि में (आपका पिछला पृष्ठ बी) अपना चालान नंबर और ग्राहक विवरण उत्पन्न करने के लिए पेज ए पर एक AJAX अनुरोध का उपयोग करें, फिर एक बार अनुरोध सही जानकारी के साथ सफलतापूर्वक वापस आ जाता है - बस अपने भुगतान गेटवे पर फ़ॉर्म जमा को पूरा करें। (पृष्ठ पृष्ठ)।

इससे उपयोगकर्ता को केवल एक बटन पर क्लिक करने और भुगतान गेटवे पर आगे बढ़ने का आपका परिणाम प्राप्त होगा। नीचे कुछ स्यूडोकोड है

HTML:

<form id="paymentForm" method="post" action="https://example.com">
  <input type="hidden" id="customInvoiceId" .... />
  <input type="hidden" .... />

  <input type="submit" id="submitButton" />
</form>

JS (सुविधा के लिए jQuery का उपयोग करके शुद्ध जावास्क्रिप्ट बनाने के लिए तुच्छ):

$('#submitButton').click(function(e) {
  e.preventDefault(); //This will prevent form from submitting

  //Do some stuff like build a list of things being purchased and customer details

  $.getJSON('setupOrder.php', {listOfProducts: products, customerDetails: details }, function(data) {
  if (!data.error) {
    $('#paymentForm #customInvoiceID').val(data.id);
    $('#paymentForm').submit();   //Send client to the payment processor
  }
});

1
इस समाधान में एक समस्या है, अगर कोई इस पृष्ठ में जावास्क्रिप्ट बंद करता है, ताज़ा करें, और सबमिट करें, यह कुछ भी बचाने के बिना भुगतान पृष्ठ पर जाएगा। यह खामी हो सकती है।
कोग्लिश

2
फिर केवल जावास्क्रिप्ट के साथ भुगतान प्रक्रिया को सेट करें? यदि JS अक्षम है, तो फॉर्म सबमिट नहीं होगा।
मिकमर्को

JS को बंद करने वाले उपयोगकर्ता को हमें कोई समस्या नहीं होनी चाहिए - पेज B पर जाने का कारण संभवतः एक फिंगरप्रिंट बनाना या एक ऑर्डर कोड जोड़ना है, आदि। इनके बिना फिर 3rd पार्टी पेज C विफल होना चाहिए, या सबसे खराब होना चाहिए। जब परिणाम बिना आदेश कोड के तीसरे पक्ष से हमारे पास वापस आता है, तो हमें आदेश को स्वीकार नहीं करना चाहिए। यह समग्र रूप से एक अच्छा समाधान है यदि जेएस स्वीकार्य है।
कोडर

19

$ _SESSION आपका मित्र है यदि आप जावास्क्रिप्ट के साथ गड़बड़ नहीं करना चाहते हैं

मान लीजिए कि आप एक ईमेल पास करने की कोशिश कर रहे हैं:

पृष्ठ A पर:

// Start the session
session_start();

// Set session variables
$_SESSION["email"] = "awesome@email.com";

header('Location: page_b.php');

और पेज B पर:

// Start the session
session_start();

// Show me the session!  
echo "<pre>";
print_r($_SESSION);
echo "</pre>";

सत्र को नष्ट करने के लिए

unset($_SESSION['email']);
session_destroy();

आप इसे तब के संस्करण को कम सुरक्षित क्यों मानते हैं?
एडम बरनै

1
नहीं, मेरा मतलब है जावास्क्रिप्ट की तुलना में नहीं। सामान्य तौर पर $ _SESSION अकेले $ _SESSION + कुकी की तुलना में थोड़ा कम सुरक्षित हो सकता है, हालांकि $ _SESSION अपने आप में बहुत सुरक्षित है। यहाँ अधिक जानकारी: stackoverflow.com/questions/17413480/session-spoofing-php
रॉबर्ट सिनक्लेयर

और सत्र बंद कैसे करें?
सईद मुहम्मद विचार

क्या आपको सत्र बंद करने की आवश्यकता है?
इवान पी।

6

आप PHP को एक POST कर सकते हैं, लेकिन तब आपके php को सभी प्रकार की जटिलताओं के साथ रिटर्न मिलेगा। मुझे लगता है कि सबसे सरल वास्तव में उपयोगकर्ता को POST करने देना होगा।

तो, आपने जो सुझाव दिया है, वह वास्तव में आपको यह हिस्सा मिलेगा:

ग्राहक पेज ए में विवरण भरते हैं, फिर पेज बी में हम एक और पेज बनाते हैं, जो वहां के सभी ग्राहक विवरण दिखाते हैं, एक CONFIRM बटन पर क्लिक करें और फिर पेज C पर पोस्ट करें।

लेकिन आप वास्तव में पेज बी पर एक जावास्क्रिप्ट सबमिट कर सकते हैं, इसलिए क्लिक की कोई आवश्यकता नहीं है। लोडिंग एनीमेशन के साथ इसे "रीडायरेक्टिंग" पृष्ठ बनाएं, और आप सेट हैं।


अब हम यही करते हैं। मुझे लगता है कि इसे हल करने के लिए कोई PHP बेहतर तर्क है। धन्यवाद। ;)
शेरो

हाँ, HTTP पर अधिक है, लेकिन मैं PHP वातावरण में काम करता हूं, इसलिए मुझे लगता है कि दोनों टैग हैं। धन्यवाद! कर्नल।
शिरो

6

मुझे पता है कि यह एक पुराना प्रश्न है, लेकिन मेरे पास jQuery के साथ एक और वैकल्पिक समाधान है:

var actionForm = $('<form>', {'action': 'nextpage.php', 'method': 'post'}).append($('<input>', {'name': 'action', 'value': 'delete', 'type': 'hidden'}), $('<input>', {'name': 'id', 'value': 'some_id', 'type': 'hidden'}));
actionForm.submit();

उपरोक्त कोड एक फॉर्म टैग बनाने के लिए jQuery का उपयोग करता है, पोस्ट फ़ील्ड के रूप में छिपे हुए फ़ील्ड्स को जोड़कर, और इसे आखिरी में सबमिट करें। पृष्ठ POST डेटा के साथ प्रपत्र लक्ष्य पृष्ठ पर अग्रेषित होगा।

इस मामले के लिए ps जावास्क्रिप्ट और jQuery की आवश्यकता है। जैसा कि अन्य उत्तरों की टिप्पणियों द्वारा सुझाया गया है, आप <noscript>जेएस अक्षम होने की स्थिति में मानक HTML फॉर्म बनाने के लिए टैग का उपयोग कर सकते हैं ।


5

एक साधारण हैक है, पोस्ट किए गए मानों का उपयोग करें $_SESSIONऔर बनाएं array, और एक बार जब आप File_C.phpइसे उपयोग करने के लिए जाते हैं तो आप इसे नष्ट करने के बाद प्रक्रिया करते हैं।


क्या आप इसका कोई छोटा उदाहरण दे सकते हैं?
कारो

3
मेरी समझ है, पेज सी एक बाहरी स्रोत है, जो पोस्ट वैल्यू लेता है, लेकिन सत्र नहीं।
नारायण भंडारी

3

मुझे पता है कि यह प्रश्न phpउन्मुख है, लेकिन POSTअनुरोध को पुनर्निर्देशित करने का सबसे अच्छा तरीका संभवतः उपयोग कर रहा है .htaccess:

RewriteEngine on
RewriteCond %{REQUEST_URI} string_to_match_in_url
RewriteCond %{REQUEST_METHOD} POST
RewriteRule ^(.*)$ https://domain.tld/$1 [L,R=307]

स्पष्टीकरण:

डिफ़ॉल्ट रूप से, यदि आप POST डेटा के साथ अनुरोध को पुनर्निर्देशित करना चाहते हैं, तो ब्राउज़र इसे GET के माध्यम से पुनर्निर्देशित करता है 302 redirectयह अनुरोध से जुड़े सभी POST डेटा को भी गिरा देता है । POST लेनदेन के किसी भी अनजाने री-सबमिट को रोकने के लिए ब्राउज़र एहतियात के तौर पर ऐसा करता है।

लेकिन क्या होगा यदि आप डेटा के साथ वैसे भी पोस्ट अनुरोध को पुनर्निर्देशित करना चाहते हैं? HTTP 1.1 में, इसके लिए एक स्थिति कोड है। स्थिति कोड 307इंगित करता है कि अनुरोध को उसी HTTP विधि और डेटा के साथ दोहराया जाना चाहिए । यदि आप इस स्थिति कोड का उपयोग करते हैं तो आपका POST अनुरोध डेटा के साथ दोहराया जाएगा।

एसआरसी


2

मुझे POST रिक्वेस्ट के साथ इसी तरह के मुद्दों का सामना करना पड़ा जहां GET रिक्वेस्ट मेरे बैकएंड पर ठीक काम कर रही थी जो कि मैं अपने वैरिएबल आदि को पास कर रहा हूं। समस्या यह है कि बैकएंड बहुत सारे रीडायरेक्ट करता है, जो फ्लॉप या व्हाट्सएप विधियों के साथ काम नहीं करता है।

तो मुझे काम करने का एकमात्र तरीका एक छिपा हुआ रूप देना था और पेज लोड होने पर एक पोस्ट सबमिट के साथ मूल्यों पर जोर देना था।

echo
'<body onload="document.redirectform.submit()">   
    <form method="POST" action="http://someurl/todo.php" name="redirectform" style="display:none">
    <input name="var1" value=' . $var1. '>
    <input name="var2" value=' . $var2. '>
    <input name="var3" value=' . $var3. '>
    </form>
</body>';

1

आप $_POSTडेटा को बचाने के लिए सत्र का उपयोग कर सकते हैं , फिर उस डेटा को पुनः प्राप्त कर सकते हैं और इसे सेट कर सकते हैं$_POST बाद के अनुरोध पर हैं।

उपयोगकर्ता सबमिट / अनुरोध तीस-submission-url.php
करो:

if (session_status()!==PHP_SESSION_ACTIVE)session_start();
     $_SESSION['POST'] = $_POST;
}
header("Location: /clean-url");
exit;

फिर ब्राउज़र /clean-submission-urlआपके सर्वर से रीडायरेक्ट और रिक्वेस्ट करता है। आपके पास यह पता लगाने के लिए कुछ आंतरिक मार्ग होंगे कि इसके साथ क्या करना है।
अनुरोध की शुरुआत में, आप करेंगे:

if (session_status()!==PHP_SESSION_ACTIVE)session_start();
if (isset($_SESSION['POST'])){
    $_POST = $_SESSION['POST'];
    unset($_SESSION['POST']);
}

अब, आपके अनुरोध के बाकी हिस्सों के माध्यम से, आप $_POSTपहले अनुरोध पर पहुंच सकते हैं।


आप वैकल्पिक रूप से $_POSTडेटा को क्वेरी स्ट्रिंग में संसाधित कर सकते हैं और इसे बाद के पृष्ठ पर इस तरह से पास कर सकते हैं। लेकिन तब डेटा बहुत बड़ा नहीं हो सकता। और यह शायद काम नहीं करता है अगर फ़ाइल अपलोड शामिल हैं, लेकिन मुझे यकीन नहीं है।
रीड

0

इसे इस्तेमाल करे:

गेटवे पर पुनर्निर्देशित करने के लिए पृष्ठ बी में http हेडर के साथ डेटा और अनुरोध भेजें

<?php
$host = "www.example.com";
$path = "/path/to/script.php";
$data = "data1=value1&data2=value2";
$data = urlencode($data);

header("POST $path HTTP/1.1\\r\
" );
header("Host: $host\\r\
" );
header("Content-type: application/x-www-form-urlencoded\\r\
" );
header("Content-length: " . strlen($data) . "\\r\
" );
header("Connection: close\\r\
\\r\
" );
header($data);
?>

अतिरिक्त हेडर:

Accept: \*/\*
User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like 
Gecko) Chrome/74.0.3729.169 Safari/537.36

0

यहाँ एक और दृष्टिकोण है जो मेरे लिए काम करता है:

यदि आपको किसी अन्य वेब पेज पर पुनर्निर्देशित करने की आवश्यकता है ( user.phpऔर एक PHP चर शामिल है $user[0]):

header('Location:./user.php?u_id='.$user[0]);

या

header("Location:./user.php?u_id=$user[0]");

वे विकल्प जीईटी प्रोटोकॉल का उपयोग करने के लिए हैं। यह क्लाइंट के ब्राउज़र पर वैरिएबल को उजागर करता है। ओपी POST के बजाय एक ही व्यवहार चाहते थे।
सर्जियो ए।

-2
function post(path, params, method) {
    method = method || "post"; // Set method to post by default if not specified.



    var form = document.createElement("form");
    form.setAttribute("method", method);
    form.setAttribute("action", path);

    for(var key in params) {
        if(params.hasOwnProperty(key)) {
            var hiddenField = document.createElement("input");
            hiddenField.setAttribute("type", "hidden");
            hiddenField.setAttribute("name", key);
            hiddenField.setAttribute("value", params[key]);

            form.appendChild(hiddenField);
         }
    }

    document.body.appendChild(form);
    form.submit();
}

उदाहरण:

 post('url', {name: 'Johnny Bravo'});
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.