I would suggest creating an invisible form in your HTML like this:
<form id="invisible_form" action="new_window.php" method="post" target="_blank">
<input id="new_window_parameter_1" name="parameter" type="hidden" value="default">
</form>
..and then submitting it via jQuery:
$('#new_window_parameter_1').val('value');
$('#invisible_form').submit();
Answer from M. Cypher on Stack OverflowI would suggest creating an invisible form in your HTML like this:
<form id="invisible_form" action="new_window.php" method="post" target="_blank">
<input id="new_window_parameter_1" name="parameter" type="hidden" value="default">
</form>
..and then submitting it via jQuery:
$('#new_window_parameter_1').val('value');
$('#invisible_form').submit();
Here is a sample how to submit a hidden form via POST:
function submit_post_via_hidden_form(url, params) {
var f = $("<form target='_blank' method='POST' style='display:none;'></form>").attr({
action: url
}).appendTo(document.body);
for (var i in params) {
if (params.hasOwnProperty(i)) {
$('<input type="hidden" />').attr({
name: i,
value: params[i]
}).appendTo(f);
}
}
f.submit();
f.remove();
}
And to use it:
submit_post_via_hidden_form(
'some link',
{
val1: val1,
val2: val2
}
);
javascript - jQuery open page in a new tab while passing POST data - Stack Overflow
javascript - Open new Tab or Window with POST [PHP] - Stack Overflow
javascript - Opening a post request in a new tab - Stack Overflow
javascript - How to replace window.open(...) with a POST - Stack Overflow
You can send a form using the target="_blank" attribute.
<form action="datadestination.php" method="POST" target="_blank" id="myform">
<input type="hidden" name="list" id="list-data"/>
<input type="submit" value="Submit">
</form>
Then in JS:
jQuery('#list-data').val(list);
jQuery('#myform').submit();
This is an implementation of Sergey's solution.
<?php // this is save.php
session_start();
// DO NOT just copy from _POST to _SESSION,
// as it could allow a malicious user to override security.
// Use a disposable variable key, such as "data" here.
// So even if someone passed _POST[isAdmin]=true, all that he would do
// is populate _SESSION[data][isAuthenticated], which nobody reads,
// not the all-important _SESSION[isAuthenticated] key.
if (array_key_exists('data', $_POST)) {
$_SESSION['data'] = $_POST['data'];
$_SESSION['data.timestamp'] = time();
// Let us let the client know what happened
$msg = 'OK';
} else {
$msg = 'No data was supplied';
}
Header('Content-Type: application/json; charset=utf8');
die(json_encode(array('status' => $msg)));
?>
In the first page:
$.post('save.php', { data: list }, function(response){
if (!response.status) {
alert("Error calling save");
return;
}
if (response.status !== 'OK') {
alert(response.status);
return;
}
// We had a response and it was "OK". We're good.
window.open('datadestination.php');
});
And in datadestination.php add the fix:
if (!array_key_exists('data', $_SESSION)) {
die("Problems? Did you perchance attempt to reload the page and resubmit?");
// For if he did, then yes, $_SESSION would have been cleared.
// Same if he is operating on more than one window or browser tab.
}
// Do something to validate data. For example we can use data.timestamp
// to assure data isn't stale.
$age = time();
if (array_key_exists($ts = 'data.timestamp', $_SESSION)) {
_SESSION[$ts];
}
if ($age > 3600) {
die("Data is more than one hour old. Did someone change server time?!?");
// I actually had ${PFY} do that to me using NTP + --hctosys, once.
// My own time zone is (most of the year) exactly one hour past GMT.
}
// This is safe (we move unsecurity-ward):
$_POST = $_SESSION['data'];
unset($_SESSION['data'], $_SESSION['data.timestamp']);
// keep things clean.
// From here on, the script behaves "as if" it got a _POST.
Update
You can actually merge save.php and datadestination.php and use a "saving stub" savepost.php that you can recycle in other pages:
<?php
session_start();
// DO NOT just copy from _POST to _SESSION,
// as it could allow a malicious user to override security.
// Use a disposable variable key, such as "data" here.
if (array_key_exists('data', $_POST)) {
// Timestamp sent by AJAX
if (array_key_exists('ts', $_POST)) {
// TODO: verify ts, but beware of time zones!
$_SESSION['data'] = $_POST['data'];
Header("Content-Type: application/json;charset=UTF-8");
die(json_encode(array('status' => 'OK')));
}
die("Error");
}
// This is safe (we move unsecurity-ward):
$_POST = $_SESSION['data'];
unset($_SESSION['data']); // keep things clean.
?>
Now your call becomes
$.post('datadestination.php', { data: list, ts: Date.now() }, function(){
window.open('datadestination.php');
});
and in your datadestination.php (or anywhere else) you add
require 'savepost.php';
In fact I made a small "library" for this, open in POST a new window :
// Arguments :
// verb : 'GET'|'POST'
// target : an optional opening target (a name, or "_blank"), defaults to "_self"
window.io = {
open: function(verb, url, data, target){
var form = document.createElement("form");
form.action = url;
form.method = verb;
form.target = target || "_self";
if (data) {
for (var key in data) {
var input = document.createElement("textarea");
input.name = key;
input.value = typeof data[key] === "object"
? JSON.stringify(data[key])
: data[key];
form.appendChild(input);
}
}
form.style.display = 'none';
document.body.appendChild(form);
form.submit();
document.body.removeChild(form);
}
};
Example :
io.open('POST', 'fileServer.jsp', {request: {key:"42", cols:[2, 3, 34]}});
To open in a new window, set the target parameter :
io.open('POST', someURL, someArgs, 'newwin');
or to ensure it's a new window/tab each time :
io.open('POST', someURL, someArgs, '_blank');
What I do is that I do a javascript AJAX post and then I take the content that I get back and place it into a new window.
Something like this (using jQuery, but you can use any AJAX implementation):
$.post(URL, DATA, function(d){
var new_window = window.open();
$(new_window.document.body).append(d);
});
Instead of writing a form into the new window (which is tricky to get correct, with encoding of values in the HTML code), just open an empty window and post a form to it.
Example:
<form id="TheForm" method="post" action="test.asp" target="TheWindow">
<input type="hidden" name="something" value="something" />
<input type="hidden" name="more" value="something" />
<input type="hidden" name="other" value="something" />
</form>
<script type="text/javascript">
window.open('', 'TheWindow');
document.getElementById('TheForm').submit();
</script>
Edit:
To set the values in the form dynamically, you can do like this:
function openWindowWithPost(something, additional, misc) {
var f = document.getElementById('TheForm');
f.something.value = something;
f.more.value = additional;
f.other.value = misc;
window.open('', 'TheWindow');
f.submit();
}
To post the form you call the function with the values, like openWindowWithPost('a','b','c');.
Note: I varied the parameter names in relation to the form names to show that they don't have to be the same. Usually you would keep them similar to each other to make it simpler to track the values.
Since you wanted the whole form inside the javascript, instead of writing it in tags, you can do this:
let windowName = 'w_' + Date.now() + Math.floor(Math.random() * 100000).toString();
var form = document.createElement("form");
form.setAttribute("method", "post");
form.setAttribute("action", "openData.do");
form.setAttribute("target", windowName);
var hiddenField = document.createElement("input");
hiddenField.setAttribute("type", "hidden");
hiddenField.setAttribute("name", "message");
hiddenField.setAttribute("value", "val");
form.appendChild(hiddenField);
document.body.appendChild(form);
window.open('', windowName);
form.submit();
I solved my problem using this dynamic form with JavaScript:
pay() {
var form = document.createElement("form");
form.target = "view";
form.method = "POST";
form.action = "https://sandbox.checkout.payulatam.com/ppp-web-gateway-payu";
var params = {
"merchantId": "508029",
"accountId": "512321",
"description": "Test PAYU"
};
for (var i in params) {
if (params.hasOwnProperty(i)) {
var input = document.createElement('input');
input.type = 'hidden';
input.name = i;
input.value = params[i];
form.appendChild(input);
}
}
document.body.appendChild(form);
form.submit();
window.open('', 'view');
}
This did what i wanted, problem solved!.
pay() {
var url = 'https://sandbox.checkout.payulatam.com/ppp-web-gateway-payu';
var data = `{
"description": "Test PAYU",
"referenceCode": "TestPayU",
"amount": "20000",
"tax": "3193",
"buyerEmail": "[email protected]",
"responseUrl": "http://www.test.com/response",
"confirmationUrl": "http://www.test.com/confirmation",
"submit": ""
}`;
this.http.post(url, data).subscribe( (response)=>{
window.open(`${url}?data=${encodeURI(data)}`, '_blank')
});
}
The magic trick is using target attribute of form element. You can submit using javascript with below code
<script type="text/javascript">
function openWindowWithPost(url, data) {
var dataForm = document.createElement("form");
dataForm.style.display = "none";
dataForm.target = "TargetWindow";//Make sure the window name is same as this value
dataForm.method = "POST";
dataForm.action = url;
for (var key in data) {
var postData = document.createElement("input");
postData.type = "hidden";
postData.name = key;
postData.value = data[key];
dataForm.appendChild(postData);
}
document.body.appendChild(dataForm);
var postWindow = window.open("", "TargetWindow", "status=0,title=0,height=600,width=800,scrollbars=1");
if (postWindow) {
dataForm.submit();
} else {
alert('You must allow popups for this map to work.');
}
//For testing invoking this function
openWindowWithPost("http://google.com", {q: 'search', from: 'custom'})
}
</script>
Same behavior can be achieved with
<!DOCTYPE html>
<html lang="en">
<head><meta charset="utf-8" /><title>Test</title></head>
<body>
<form method="POST" enctype="multipart/form-data" target="TargetWindow" action="http://google.com" onsubmit="openTargetWindowAndSubmit()">
<input type="file" accept="image/*" />
<input type="submit" value="Submit"/>
</form>
<script type="text/javascript">
function openTargetWindowAndSubmit() {
//We are just making sure the target window is available before submiting the form
window.open("", "TargetWindow", "status=0,title=0,height=600,width=800,scrollbars=1");
}
</script>
</body>
</html>
Note: Using simply target='_blank' or target='TargetWindow' opens generally a new tab. This is fine when new tab is OK with you. But when you want to submit in POP UP window, than giving the window width and height is required.
So your only option would be to create a form, set the target to _blank, and trigger the submission.
<form action="/action" method="post" target="_blank" id="frm">
<input type="hidden" name="foo" value="your huge string">
</form>
You can create it with JavaScript and submit it.
document.getElementById("frm").submit()
I would probably go for using a form, like so:
<form action="sample.php" method="post" target="_blank">
<input type="hidden" name="name1" />
<input type="hidden" name="name2" />
...
<input type="hidden" name="name20" />
<input type="submit" value="Go to page">
</form>
This is the most cross-browser JS-failsafe basic html version way of achieving this task that I can think of...
If you need to dynamically add form fields to the form, I believe you will find this question: Jquery - Create hidden form element on the fly handy. Copying the modified answer:
$('<input type="hidden" name="myfieldname" value="myvalue">').appendTo('form');
One way would be to dynamically create a hidden form and then submit it, make sure you encode the input:
var params = [['someKey0', 'someValue0'], ['someKey1', 'someValue1'], ['someKey2', 'someValue2'], ['someKey3', 'someValue3']];
var inputs = $.map(params,function(e,i){
return '<input type="hidden" name="'+e[0]+'" value="'+encodeURIComponent(e[1])+'"/>';
});
var form ='<form action="sample.php" id="hidden-form" method="post" target="_blank">'+inputs.join('')+'</form>';
$('#hidden-div').html(form);
$('#hidden-form').submit();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="hidden-div"></div>