1

阅读了大量与我想做的相关的帖子后,我很确定这是不可能的,但无论如何我都会问这个问题,希望有人可能以前解决过这个问题,或者可以指出我正确的方向一个解法。

我有一个复杂的 PHP/MySQL Web 应用程序,我希望保持浏览器选项卡/窗口独立。例如,用户可以在一个选项卡中对数据库进行搜索,并在另一个选项卡中进行另一次搜索,并且在进行搜索时设置和存储的各种参数仅链接到相关的浏览器选项卡。重新加载选项卡或在搜索中进一步移动(分页系统限制存储的结果数量)不会干扰其他搜索选项卡,并且仅使用当前选项卡标识的参数。

我的想法是将搜索和其他与浏览器选项卡有关的参数存储在数据库表中,该数据库表由与选项卡相关联的一些唯一标识符作为键控。

我不能使用 PHP 会话,因为它们在选项卡中很常见。PHP 作为服务器端,不知道请求来自哪个选项卡/窗口。Cookie 与会话一样,在选项卡中很常见。

跟踪不同选项卡/窗口的解决方案似乎是 javascript 的 sessionStorage,乍一看似乎很理想——我可以设置一个浏览器选项卡独有的 js 会话变量,并将其回显到 PHP 脚本,并且在每个选项卡中,我可以设置并保持一个独立的值。然而,我需要将该 js 会话值分配给 PHP 变量,并且这需要在 PHP 脚本的搜索部分运行之前可用。除了加载 URL 之外,用户方面没有任何交互(即没有表单提交等)。

我遇到过建议 AJAX/JQuery 的解决方案,但这些都需要在 PHP 脚本运行后的表单和某种类型的用户交互,并且我见过的大多数示例都写入 div 的 innerHtml。这些都不能实现我想要的。

最近,我一直在玩弄通过网关 URL 解析应用程序的每个页面的想法,该 URL 只需加载一个创建 js 会话(如果尚未创建)的 javascript 脚本,然后重定向到具有唯一标识符的实际 PHP 脚本作为查询字符串的一部分。但这似乎涉及不必要的开销。

任何建议甚至解决方案都将不胜感激。

————>

回应 ADyson(因为评论框太短):

该应用程序在这里:https ://testdrive.wikindx.com/

它是为学者/研究学生管理参考资料的。它们都以不同的方式工作,包括一些人喜欢打开多个标签来进行不同的搜索,这就是问题所在。例如,每次搜索都会产生显示在网页上的结果,以及搜索参数等其他信息(供参考)。分页系统(即显示例如 10 个结果/页)被设计为使用更快和更有效的 SQL 调用进入下一页——所有繁重的工作都在初始搜索中完成。搜索参数和摘要结果/总计在第一次调用时完成,这些必须保存在某个地方以及核心 SQL 子查询中。基本上,有一些数据在搜索的不同页面中是通用的,这些数据必须存储在某个地方,并且对于该浏览器选项卡中的搜索来说是唯一的。

4

2 回答 2

2

选项卡的 URL 必须是唯一的。互联网是无状态的,因此浏览器在刷新后不知道它是标签一还是标签二,除非网址告诉它。

如果您在选项卡 url 中有一个标识符,例如数字或哈希,则可以使用它来保存并从会话中返回特定信息:

$_SESSION['tabs'][0]ETC

因此,启动新选项卡/搜索将需要您跟踪和增加用户的选项卡 ID:

$tabID = sizeof($_SESSION['tabs']);或使用一些随机哈希生成器。

您已经提到使用 ajax,这也是一种可能的选择。有了这个,您可以将标识符存储在 url 的哈希中#tab-1,否则使用相同的 url。然后,您需要使用 javascript 从选项卡的哈希中获取标识符并发送一个请求,包括通过 ajax 请求服务器 (PHP) 为您生成与其匹配的特定搜索结果/页面,然后您可以使用它来填充页面。

于 2020-11-03T10:31:50.280 回答
0

这是我的解决方案。它使用 javascript 检查选项卡/窗口的唯一 ID 是否存在,并使用 sessionStorage 来存储该唯一 ID。如果用户使用不使用 sessionStorage 的旧浏览器,我还没有测试我的应用程序是否仍然有效——这目前在 Firefox、Safari 和 Chrome 中有效。

我的 index.php 的业务端。一旦完成了一些基本的环境配置(这是 WIKINDX_URL_BASE 等的来源),javascript 是第二个运行的东西:

/**
  * Generate/return the unique browser tab/window identifier
  */
$script = WIKINDX_URL_BASE . '/gatekeeper.js?ver=' . WIKINDX_PUBLIC_VERSION;
$qs = $_SERVER['QUERY_STRING'] ? '?' . $_SERVER['QUERY_STRING'] : FALSE;
$url = WIKINDX_URL_BASE . '/index.php' . $qs;
if (!array_key_exists('browserTabID', $_GET)) {
// go into gatekeeper for a redirect and addition of a browserTabID to the querystring
print <<< END
<script src="$script"></script>
<script>redirectSet("$url", "$qs")</script>
END;
}
else {
// go into gatekeeper to check if browserTabID is unique to the tab (perhaps user has `opened link with browserTabID in a new tab/window)`
$id = $_GET['browserTabID'];
print <<< END
<script src="$script"></script>
<script>getBrowserTabID("$url", "$qs", "$id")</script>
END;
}

还有我的 gateway.js:

// gatekeeper.js
/**
 * No browserTabID yet set so generate one and redirect
 */
function redirectSet(url, qs)
{
    var browserTabID;
    if ((sessionStorage.getItem('browserTabID') == null) || !sessionStorage.getItem('browserTabID')) {
        browserTabID = uuidv4();
        sessionStorage.setItem('browserTabID', browserTabID);
    } else { // This shouldn't be necessary but is here for completeness. Perhaps of use in the future . . .
        browserTabID = sessionStorage.getItem('browserTabID');
    }
    if (qs) {
        url = url + '&browserTabID=' + browserTabID;
    } else {
        url = url + '?browserTabID=' + browserTabID;
    }
    window.location.href = url;
}

/**
 * browserTabID in the URL. 
 * If the same as the session, URL is opened in existing tab/window so return doing nothing.
 * If not the same as the session (session is null probably), URL is opened in a new tab/window so generate browserTabID and redirect
 */
function getBrowserTabID(url, qs, browserTabID)
{
    if (browserTabID == sessionStorage.getItem('browserTabID')) { // Continuing in same tab/window
        return;
    }
// User has opened a link in a new tab/window – generate a new ID
    browserTabID = uuidv4();
    sessionStorage.setItem('browserTabID', browserTabID);
    if (qs) {
        url = url + '&browserTabID=' + browserTabID;
    } else {
        url = url + '?browserTabID=' + browserTabID;
    }
    window.location.href = url;
}

/**
 * Code from https://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid
*/
function uuidv4() {
  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
    var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
    return v.toString(16);
  });
}

在 index.php 中运行代码后,我可以访问 $_GET['browserTabID'] ,然后我可以使用它来访问数据库表行。

标记

于 2020-11-05T05:24:40.053 回答