简体   繁体   English

跨多个选项卡的父子导航

[英]Parent-Child navigation across multiple tabs

please bear with me for the explanation, it's necessary. 请耐心解释,这是必要的。

System background: I am creating a parent->child navigation system for the backend of a CMS. 系统背景:我正在为CMS的后端创建父 - >子导航系统。 I build URLs like so: [domain.ext]/[moduleName]/[objectName]/[actionName]/[ID #1]/[ID #2] . 我建立如下URL: [domain.ext]/[moduleName]/[objectName]/[actionName]/[ID #1]/[ID #2]

The URL explained (eg example.com/PageManagement/Page/Modify/7/13 ): 解释的URL(例如example.com/PageManagement/Page/Modify/7/13 ):

  • moduleName : the name of the module the object belongs to (eg "PageManagement") moduleName :对象所属模块的名称(例如“PageManagement”)
  • objectName : the name of the object (eg "Page") objectName :对象的名称(例如“Page”)
  • actionName : the name of the action (eg "Modify") actionName :操作的名称(例如“修改”)
  • ID #1 : either the ID of the record the action is being performed on, or the ID of the object's parent ID#1:正在执行的动作的记录的任一的ID, 对象的父的ID
  • ID #2 : the ID of the record the action is being performed on, but only if ID #1 is filled with a parent ID ID#2 :正在执行操作的记录的ID, 但仅当ID#1填充了父ID时

Navigation happens by parsing the URL for its components, reducing the names to system IDs etc., and then retrieving the fields and data which are to be displayed on the page. 通过解析其组件的URL,将名称减少到系统ID等,然后检索要在页面上显示的字段和数据来进行导航。
To ensure the URL remains readable and logically understandable I don't add multiple layers of parent ID's to the URL, but rather keep the last few parent IDs in the PHP $_SESSION array, so I can determine on navigation whether a different parent ID has to be added. 为了确保URL保持可读性和逻辑上可理解性,我不会在URL中添加多个父ID层,而是将最后几个父ID保存在PHP $_SESSION数组中,这样我就可以确定导航是否有不同的父ID待补充。

Example: image we have the objects Page->Extension->Field , which are all in the module PageManagement and parented from left to right. 示例: image我们有对象Page->Extension->Field ,它们都在模块PageManagement ,从左到右为父级。 Now let's say we have a Page with ID 2, an Extension with ID 8, and a Field with ID 17. The URL for editing the Field would be example.com/PageManagement/Field/Modify/8/17 , because we are editing Field 17, which has Extension 8 as parent. 现在假设我们有一个ID为2的页面,一个ID为8的扩展,一个ID为17的字段。编辑该字段的URL将是example.com/PageManagement/Field/Modify/8/17 ,因为我们正在编辑字段17,其中扩展8为父级。 The URL for editing the Extension would be example.com/PageManagement/Extension/Modify/2/8 , because we are editing Extension 8, which has Page 2 as parent. 用于编辑扩展的URL将是example.com/PageManagement/Extension/Modify/2/8 ,因为我们正在编辑Extension 8,它具有父级。 Editing the Page would simply be example.com/PageManagement/Page/Modify/2 , because it has no parent. 编辑页面只是example.com/PageManagement/Page/Modify/2 ,因为它没有父页面。

Problem: Now, all of this works perfectly. 问题:现在,所有这一切都很完美。 However, if multiple tabs are opened they share the same $_SESSION , so navigating in one tab can throw off the parent history for the other tab. 但是,如果打开多个选项卡,则它们共享相同的$_SESSION ,因此在一个选项卡中导航可以抛弃另一个选项卡的父历史记录。 It still goes right in almost all cases, but the fact I can cause it is bad (since someone can be adding/deleting/editing data without knowing they are actually in the wrong parent list). 几乎所有情况下它仍然是正确的,但我可以导致它的事实是坏的(因为有人可以添加/删除/编辑数据而不知道它们实际上在错误的父列表中)。

What I need: I need a way, with each request, to determine from which tab it came, most likely by generating some form of UID per tab and sending that with each request. 我需要的是:我需要一种方法,通过每个请求,确定它来自哪个选项卡,最有可能是通过为每个选项卡生成某种形式的UID并将其与每个请求一起发送。 My system can then store the navigation history per tab, instead of per session. 然后,我的系统可以存储每个选项卡的导航历史记录,而不是每个会话。

Considered solutions 考虑的解决方案

  • Generating a UID per page session, and storing this in the Window.sessionStorage (which gets reset for each new window/tab). 生成每页UID会话,并将其存储在Window.sessionStorage (每个新窗口/选项卡都会重置)。 This would allow me to generate one if none is set yet (so a new tab), and thus have a different one stored (and remembered) per page session. 这将允许我生成一个如果还没有设置(所以一个新的选项卡),因此每页会话存储(和记住)不同的一个。
    • Problem: I don't know how I can get that UID sent to the server with each request. 问题:我不知道如何通过每个请求将UID发送到服务器。 Session cookies seem to be shared between all tabs (makes sense since they share a session). 会话cookie似乎在所有选项卡之间共享(因为它们共享会话,所以有意义)。
  • Generating a UID per page session, and appending that to the URL as a query string. 生成每页UID会话,并将其作为查询字符串附加到URL。
    • Problem: I might as well not have nice URLs, and if someone (accidentally) edits/removes it, it will still not work. 问题:我可能也没有很好的网址,如果有人(不小心)编辑/删除它,它仍然无法正常工作。 Also, copy/pasting the URL will be a problem. 此外,复制/粘贴URL将是一个问题。
  • Generating a UID per page session, and prepending that to the URL before the moduleName . 生成每页会话的UID,并将其添加到moduleName之前的URL。
    • Problem: It is still visible/editable/removable, and if they do it will still not work. 问题:它仍然可见/可编辑/可移动,如果他们这样做仍然无法正常工作。 Also, copy/pasting the URL will be a problem. 此外,复制/粘贴URL将是一个问题。

If anyone can solve the problems mentioned for the solutions above, or come up with a completely new solution, that would be amazing. 如果有人能够解决上述解决方案中提到的问题,或者想出一个全新的解决方案,那将是惊人的。 Obviously I'd prefer make as few changes as possible to how the URL system works, but if that is the only solution, so be it... 显然,我更希望尽可能少地改变URL系统的工作方式,但如果这是唯一的解决方案,那就这样吧......

There's a basic flaw in your request design that's causing you all the trouble. 您的请求设计中存在一个基本缺陷,这会给您带来麻烦。
A system should strive to include all relevant information within a single request whenever possible. 系统应尽可能在单个请求中包含所有相关信息。 In your case, that means ditching the mechanism that "remembers" earlier requests (state..) in the $_SESSION and instead pass all the information in the request. 在您的情况下,这意味着放弃在$_SESSION中“记住”先前请求(状态..)的机制,而是传递请求中的所有信息。 It can be in the URL ("address" and/or query string), the headers when appropriate (Usually using cookies. Probably inappropriate in this case) or body (same way as POSTed forms pass the payload). 它可以在URL(“地址”和/或查询字符串)中,适当时的标题(通常使用cookie。在这种情况下可能不合适)或正文(与POST表单相同的方式传递有效负载)。

There are numerous reasons to choose this path, to name a few: 选择此路径的原因有很多,仅举几例:

  1. Improve logging. 改善日志记录
  2. Ease debugging. 轻松调试。
  3. Enable simple, URL based linking (when using only the URL for requests). 启用简单的基于URL的链接(仅使用请求的URL时)。
  4. Reduce risk of incorrect caching (local or remote). 降低不正确缓存(本地或远程)的风险。
  5. Support multiple "simultaneous" requests -> Will help overcome current issue :-) 支持多个“同时”请求 - >将有助于克服当前问题:-)

As always, no rule goes without exceptions. 一如既往,没有例外规则。 In this case, the most common piece of information that is NOT suitable to be included in each request is authentication information (username, password, etc...) 在这种情况下,不适合包含在每个请求中的最常见信息是身份验证信息(用户名,密码等...)

To summarize, you should strongly consider reconstructing your requests such that all required information is available. 总而言之,您应该强烈考虑重建您的请求,以便获得所有必需的信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM