jQuery打开一个新标签页并传递POST数据

22

我有一个名为“list”的 JavaScript 变量。我需要将它作为 POST 数据发送到另一个页面,并在新标签页中打开该页面(POST 数据也要出现)。

这段代码:

jQuery.post('datadestination.php', list);

能够成功发送数据,但它会在同一个标签页中打开页面。

我看到了一些类似问题的解决方案,如使用不可见表单等方法,但我无法使它们起作用。有没有更简单的解决方案?


1
在https://dev59.com/p2w05IYBdhLWcg3wy012中描述的解决方案似乎有效。你有什么具体的问题吗?发生了什么事情? - LSerni
1
你还可以调用一个JavaScript函数,动态创建带有 target='_blank' 属性的表单:http://stackoverflow.com/questions/7013109/submit-is-not-a-function-error-in-firefox-in-dynamically-created-form-without - Stefan
3个回答

24

你可以使用 target="_blank" 属性发送表单。

<form action="datadestination.php" method="POST" target="_blank" id="myform">
  <input type="hidden" name="list" id="list-data"/>
  <input type="submit" value="Submit">
</form>

然后在 JS 中:

jQuery('#list-data').val(list);
jQuery('#myform').submit();

它会打开一个额外的空白标签页,你有什么想法是什么原因? - user1500341

18
这是Sergey解决方案的实现。
<?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)));
?>

在第一页中:
$.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');
});

在datadestination.php中添加以下修复代码:

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)) {
    $age -= $_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.

更新

您实际上可以将save.phpdatadestination.php合并,并使用一个“保存存根”savepost.php,您可以在其他页面中重复使用:

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

现在您的呼叫已经变成了:
$.post('datadestination.php', { data: list, ts: Date.now() }, function(){
    window.open('datadestination.php');
});

在您的datadestination.php(或任何其他地方)中添加以下内容:
require 'savepost.php';

太棒了!我本来可以自己写的,但是让其他遇到同样问题的人看到这个可行的解决方案也是很好的。 - zorza
1
哦,我不知怎么忘记你想要它在一个新的标签页中打开了。已修复。 - LSerni

17
我建议:
  1. 使用 jquery.post() 函数将该列表传递并保存在 SESSION 数组中。
  2. 使用 window.open() 函数在新标签页中打开相同的文件/地址/URL。
  3. SESSION 数组中检索保存的数据。
这对我来说看起来很简单和干净。

这实际上很棒... 不知何故,我无法忍受这个看不见的表单。 - zorza
如果用户打开多个选项卡并且表单的值发生更改,则此功能不是很有用。 - Leandro Bardelli

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接