ajax 在 javascript 中,如何唯一地识别一个浏览器窗口和另一个位于同一个基于 cookied 的 sessionId 下的浏览器窗口
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/864942/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
In javascript, how can I uniquely identify one browser window from another which are under the same cookiedbased sessionId
提问by srmark
The users of my web application may have more than one browser window open and pointed to the same page. I would like the state of certain things in the page (loaded via ajax) to be retained across postbacks. I can either store in a cookie or on my server. Either way, I can't think of how I can distinguish each window.
我的 Web 应用程序的用户可能打开了多个浏览器窗口并指向同一个页面。我希望页面中某些内容的状态(通过 ajax 加载)在回发中保留。我可以存储在 cookie 中或我的服务器上。无论哪种方式,我都想不出如何区分每个窗口。
For example, say user Bob has two browser windows open to the ListOfSomething page. Each list has a LoadedPageNumberattribute which I need to persist. Otherwise users always end up on page 1 when they refresh. Bob might have loaded browser window 1 and pointed it to page 5 and then loaded browser window 2 and pointed it to page 14. If I just store the attribute based on session id, Bob will get page 14 in window 1 if he refreshes it.
例如,假设用户 Bob 有两个浏览器窗口打开 ListOfSomething 页面。每个列表都有一个我需要保留的LoadedPageNumber属性。否则,用户刷新时总是会在第 1 页上结束。Bob 可能已加载浏览器窗口 1 并将其指向第 5 页,然后加载浏览器窗口 2 并将其指向第 14 页。如果我仅根据会话 id 存储属性,则 Bob 将在刷新窗口 1 时获得第 14 页。
Note that my state variables are actually much more complex than this simple example and my inability to persist them could lead to big problems (weaknesses in my app).
请注意,我的状态变量实际上比这个简单的示例复杂得多,我无法持久保存它们可能会导致大问题(我的应用程序中的弱点)。
I need some kind of browser window id or something. It of course needs to be a cross-browser solution (IE6+, Wekbit?+, FF2+)
我需要某种浏览器窗口 ID 或其他东西。它当然需要是一个跨浏览器的解决方案(IE6+、Wekbit?+、FF2+)
Any ideas?
有任何想法吗?
Note on relevance: Keep in mind that this is useful also for the case where you're mixing older forms based pages with newer AJAX enabled items. Sometimes you need to postback the forms and you don't want to loose some client side state values.
关于相关性的注意事项:请记住,这对于将旧的基于表单的页面与支持 AJAX 的新项目混合在一起的情况也很有用。有时您需要回发表单并且不想丢失一些客户端状态值。
回答by Roy Rico
you could set your own window name, the exact syntax escapes me right now, but you can use the current time and session id to create a unique id on window load, then use that id
您可以设置自己的窗口名称,确切的语法现在让我无法理解,但是您可以使用当前时间和会话 ID 在窗口加载时创建唯一 ID,然后使用该 ID
This would be done the same way you set a name in the javascript window.open() function, (but you can do it to self, instead of new window)
这将与您在 javascript window.open() 函数中设置名称的方式相同,(但您可以对 self 执行此操作,而不是对新窗口执行此操作)
googling shows:
谷歌搜索显示:
self.window.name = myclass.getUniqueWindowId( thisSession );
self.window.name = myclass.getUniqueWindowId( thisSession );
UPDATE
更新
Regarding your need to save this from refresh to refresh, i did some tests and it looks to save it from refresh to refresh. Using Firefox 3, on initial load, the window name is blank, and pressing CTRL+R over and over, and the window name was populated. i then commented out the setting the name code and reloaded and it still retained the name.
关于您需要将它从刷新保存到刷新,我做了一些测试,它看起来是从刷新保存到刷新。使用 Firefox 3,在初始加载时,窗口名称为空白,并一遍又一遍地按 CTRL+R,并填充窗口名称。然后我注释掉了名称代码的设置并重新加载,它仍然保留了名称。
<script type="text/javascript">
alert( self.window.name );
self.window.name = "blah";
</script>
UPDATE
更新
I have to make noticed the comment below on jQuery's 'jquery-session' plugin, which really works and offers way more than what's discussed here.
我必须注意下面关于 jQuery 的 'jquery-session' 插件的评论,它确实有效并且提供了比这里讨论的更多的方式。
Although, one should also make it clear that it relies on HTML5's Web Storage, not supported by older IEversions.
虽然,还应该明确指出,它依赖于 HTML5 的 Web 存储,旧版 IE 不支持。
Corporate still depends heavily on IE 7 ('and below' here in Brazil).
企业仍然严重依赖 IE 7(在巴西这里是“及以下”)。
Based on self.window.name, THE solution for everything non-compliant to HTML5, I offer the following code snippet as a cross-browser solution:
基于self.window.name,所有不符合 HTML5 的解决方案,我提供以下代码片段作为跨浏览器解决方案:
<script src="http://code.jquery.com/jquery-latest.min.js" type="text/javascript"></script>
<script language="javascript" type="text/jscript">
//----------------------------------------------------------------------
//-- guarantees that window.name is a GUID, and that it would
//-- be preserved whilst this window's life cicle
//----------------------------------------------------------------------
//-- window.name will be set to "GUID-<SOME_RANDOM_GUID>"
//----------------------------------------------------------------------
$(window).load(
function () {
//----------------------
var GUID = function () {
//------------------
var S4 = function () {
return(
Math.floor(
Math.random() * 0x10000 /* 65536 */
).toString(16)
);
};
//------------------
return (
S4() + S4() + "-" +
S4() + "-" +
S4() + "-" +
S4() + "-" +
S4() + S4() + S4()
);
};
//----------------------
if (!window.name.match(/^GUID-/)) {
window.name = "GUID-" + GUID();
}
}
) //--------------------------------------------------------------------
</script>
I found the GUID function here(for which I proposed some code clean-up).
我在这里找到了 GUID 函数(为此我提出了一些代码清理)。
回答by Herms
What about having your server randomly generate an ID and have that stored in the page (some javascript variable) when it's served? Then just include that ID in the ajax request. It wont' help on a browser refresh, but as long as the user leaves that page in place (and just lets the ajax stuff do its thing) it should work fine.
让您的服务器随机生成一个 ID 并将其存储在页面中(一些 javascript 变量)如何?然后只需在 ajax 请求中包含该 ID。它不会对浏览器刷新有帮助,但只要用户将该页面留在原地(并且只让 ajax 做它的事情)它应该可以正常工作。
回答by GobiRan
It's a long time ago, but the answer of Roy Rico helped me today, so I want to share my experience. To handle page refresh and page backbutton uses, I am doing it like that:
很久以前了,但是今天Roy Rico的回答对我很有帮助,所以我想分享一下我的经验。为了处理页面刷新和页面后退按钮的使用,我是这样做的:
- Your server checks if the browser sends the GUID with his request (only works with ajax or form submit)
- If it is not there (browser refresh, backbutton) it just sends back a page with a small JavaScript script. This script creates the GUID and puts it into the window.name storage as described above. After that the script creates a form with the GUID as hidden field and submits it to the server. The action attribute uses the same URL as before (window.location.href)
- 您的服务器检查浏览器是否随其请求发送 GUID(仅适用于 ajax 或表单提交)
- 如果它不存在(浏览器刷新、后退按钮),它只会返回一个带有小 JavaScript 脚本的页面。该脚本创建 GUID 并将其放入 window.name 存储中,如上所述。之后,脚本创建一个以 GUID 作为隐藏字段的表单并将其提交给服务器。action 属性使用与之前相同的 URL (window.location.href)
--> Now the server recognizes the GUID and can deliver the content as needed.
--> 现在服务器识别出GUID,可以根据需要传送内容了。
Here is my code (the GUID I create on the server for security reasons, the syntax "${gUid} is from freemarker and just inserts the Guid from the server):
这是我的代码(出于安全原因,我在服务器上创建的 GUID,语法“${gUid} 来自 freemarker,只是从服务器插入 Guid):
<script>
$(window).load(
function () {
if (!window.name.match(/^GUID-/)) {
window.name = "GUID-" + "${gUid}";
}
$('<form action='+window.location.href+' method="POST"><input type="hidden" name="X-GUID" id="X-GUID" value='+window.name+'></form>').appendTo('body').submit();
}
);
</script>
Hope that helps someone
希望能帮助某人
By the way, this technique should only be used on "NON SEO PAGES", because of the need of JavaScript to get the content. But in general SEO pages have no need of identifying the tab session.
顺便说一句,这种技术应该只用于“非 SEO 页面”,因为需要 JavaScript 来获取内容。但通常 SEO 页面不需要识别标签会话。
Of course nowadays you can make use of the HTML5 session storage, but I don't want to rely on that, because I also need older browser to work well.
当然,现在您可以使用 HTML5 会话存储,但我不想依赖它,因为我还需要旧版浏览器才能正常工作。
回答by Amjad Abdul-Ghani
You can use HTML5 session Storage ,just generate an unique id and set it on the session storage ! what is cool about that each window or tab has its own session storage. for example :
您可以使用 HTML5 会话存储,只需生成一个唯一的 id 并将其设置在会话存储上!每个窗口或选项卡都有自己的会话存储有什么很酷的。例如 :
if we run the following on 3 windows:
如果我们在 3 个窗口上运行以下命令:
window 1:
sessionStorage.setItem('key' , 'window1');
窗口 1:
sessionStorage.setItem('key' , 'window1');
window 2:
sessionStorage.setItem('key' , 'window2');
窗口 2:
sessionStorage.setItem('key' , 'window2');
window 3:
sessionStorage.setItem('key' , 'window3');
窗口 3:
sessionStorage.setItem('key' , 'window3');
sessionStorage.getItem('key' );<<< this will return corresponding value on window!
sessionStorage.getItem('key' );<<< 这将在窗口上返回相应的值!
window 1:
sessionStorage.getItem('key' );returns window 1
窗口 1:
sessionStorage.getItem('key' );返回窗口 1
window 2:
sessionStorage.getItem('key' );returns window 2
窗口 2:
sessionStorage.getItem('key' );返回窗口 2
window 3:
sessionStorage.getItem('key');returns window 3
窗口 3:
sessionStorage.getItem('key');返回窗口 3
I believe you are trying to save a variable (separately on each tab/window).
我相信您正在尝试保存一个变量(分别在每个选项卡/窗口上)。
sessionStorage works as charm.
sessionStorage 很有魅力。
The only problem you may face that browser should support HTML 5.
您可能面临的唯一问题是浏览器应该支持 HTML 5。
回答by Attila
window.name can be overwritten by custom javascript libraries, datetimepickers etc.
window.name 可以被自定义 javascript 库、datetimepickers 等覆盖。
Instead of window.name I suggest you to use the DOM head meta tag to store your id
我建议您使用 DOM head 元标记代替 window.name 来存储您的 id
<html><head><meta id="windowID" content="{YOUR ID}">
After page is loaded, you have to load everything via ajax in that window, then you can attach this ID to every request as a header (or data) value. For example in JQuery with this code:
页面加载后,您必须通过该窗口中的 ajax 加载所有内容,然后您可以将此 ID 作为标头(或数据)值附加到每个请求。例如在 JQuery 中使用以下代码:
$(document)
.ajaxSend(function(event, jqXHR, ajaxOptions) {
jqXHR.setRequestHeader('windowID',
document.getElementById('windowID').content);
})
To use this solution, you have to have access to custom header values on server side. For example in Java servlet:
要使用此解决方案,您必须有权访问服务器端的自定义标头值。例如在 Java servlet 中:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String windowName = request.getHeader("windowID");
If you store paging, sorting, filtering etc. information on server side as session attribute, you should store them separately attached to the separate window ID-s.
如果你在服务器端存储分页、排序、过滤等信息作为会话属性,你应该单独存储它们附加到单独的窗口ID-s。

