Github跨tabs/windows检测用户登录状态

本文解析了GitHub如何实现在不同浏览器窗口间同步用户的登录状态。通过监听LocalStorage的StorageEvent事件,并根据用户登录信息的变化来更新各窗口的状态。
访问 Github 网站时,如果多个 Window 或 Tab 同时访问 github.com,在任何一个页面做登录或登出处理,其他页面会立即提示用户已经登录或登出,需要重新加载页面。

[b](1)操作演示[/b]
同时2个窗口打开github.com
[img]http://dl2.iteye.com/upload/attachment/0125/4646/270ad599-3d6a-347e-909c-94fcdd53fcda.png[/img]

在其中一个窗口登录用户
[img]http://dl2.iteye.com/upload/attachment/0125/4648/8e7edd1c-82ad-3689-be59-45e6412aea42.png[/img]

另外一个窗口显示需要Reload
[img]http://dl2.iteye.com/upload/attachment/0125/4650/e681f557-750a-3f14-b7f4-320875ce7571.png[/img]

刷新窗口后
[img]http://dl2.iteye.com/upload/attachment/0125/4652/cc8a05c4-5f88-3fb2-b53b-fdcff5956c05.png[/img]

在一个窗口做登出处理,另外一个窗口也会提示需要Reload
[img]http://dl2.iteye.com/upload/attachment/0125/4654/a4ccbc2d-eb42-3ac8-b027-69f51210ca65.png[/img]

[b](2)代码分析[/b]
浏览器右键查看源代码可以看到以下代码,其中"d-none"就是控制是否显示div的。
  <div class="js-stale-session-flash stale-session-flash flash flash-warn flash-banner d-none">
<svg aria-hidden="true" class="octicon octicon-alert" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M8.865 1.52c-.18-.31-.51-.5-.87-.5s-.69.19-.87.5L.275 13.5c-.18.31-.18.69 0 1 .19.31.52.5.87.5h13.7c.36 0 .69-.19.86-.5.17-.31.18-.69.01-1L8.865 1.52zM8.995 13h-2v-2h2v2zm0-3h-
2V6h2v4z"/></svg>
<span class="signed-in-tab-flash">You signed in with another tab or window. <a href="">Reload</a> to refresh your session.</span>
<span class="signed-out-tab-flash">You signed out in another tab or window. <a href="">Reload</a> to refresh your session.</span>
</div>

[img]http://dl2.iteye.com/upload/attachment/0125/4656/00ea2d0c-95af-3cbc-adab-635e4a2960b1.png[/img]

查看源代码可以看到页面总共引入了2个JavaScript文件:
<script crossorigin="anonymous" integrity="sha256-LrSxxxxx" src="https://assets-cdn.github.com/assets/frameworks-2ebxxxxx.js"></script>
<script async="async" crossorigin="anonymous" integrity="sha256-izZxxxxx" src="https://assets-cdn.github.com/assets/github-8b3xxxxx.js"></script>


继续查看第二JavaScript文件并搜索"js-stale-session-flash",可以找到以下代码,可见是通过监听Storage数据变更StorageEvent事件后是否存在logged-in来判断的!
window.addEventListener("storage",function(e){if(e.storageArea===localStorage&&"logged-in"===e.key&&e.newValue!==a){a=e.newValue;var n=document.querySelector(".js-stale-session-flash");r["default"](n instanceof HTMLElement,"Flash element must exist and be an HTMLElement"),n.classList.toggle("is-signed-in","true"===a),n.classList.toggle("is-signed-out","false"===a),n.classList.remove("d-none"),

[img]http://dl2.iteye.com/upload/attachment/0125/4658/ee5dc309-6847-384a-8f9a-cbe5a09bb2c2.png[/img]

继续在第二JavaScript文件里搜索"logged-in",可以看到以下代码,可见根据head里<meta name="user-login" content="">的content的值来判断的,有值时为true。有值的情况下是:[b]<meta name="user-login" content="rensanning">[/b]
!function(){var e=document.querySelector("meta[name=user-login]");if(e instanceof HTMLMetaElement){var n=e.content,a=String(!!n.length);try{localStorage.setItem("logged-in",a)}catch(i){return}

[img]http://dl2.iteye.com/upload/attachment/0125/4660/0e764082-e84a-3b0d-93e7-a5be46be77da.png[/img]

[color=blue][b]总结一下:监听LocalStorage的StorageEvent事件![/b][/color]

StackOverflow上也有相关的问题:[url=https://stackoverflow.com/questions/39550656/how-does-github-detect-signing-in-out]https://stackoverflow.com/questions/39550656/how-does-github-detect-signing-in-out[/url]
<think>我们使用pychrome库来与Chrome浏览器的调试端口进行通信。要检测浏览器是否已启用debug模式(即是否打开了调试端口),我们尝试连接该端口并检查是否能够成功建立连接。 步骤: 1. 创建一个Browser对象,指定调试端口(debug_port)。 2. 尝试调用Browser的list_tab方法,该方法会返回当前打开的标签页信息。如果连接成功,则说明调试模式已启用。 3. 如果连接失败(抛出异常),则说明无法连接到调试端口,即浏览器未启用调试模式。 注意:需要确保浏览器已经以调试模式启动(例如:`chrome.exe --remote-debugging-port=9222`) 代码示例: ```python import pychrome def check_debug_mode_enabled(debug_port=9222): try: # 创建Browser对象,指定host和port browser = pychrome.Browser(url=f"http://127.0.0.1:{debug_port}") # 尝试获取标签页列表 tabs = browser.list_tab() # 如果获取到标签页列表,说明调试模式已启用 return True except Exception as e: # 连接失败,调试模式未启用或端口不对 print(f"Error: {e}") return False # 调用函数 if check_debug_mode_enabled(): print("Debug模式已启用") else: print("Debug模式未启用") ``` 说明: - 这里我们使用默认的端口9222,如果您的浏览器使用其他端口,请更改debug_port参数。 - 当浏览器以调试模式启动时,会打开一个端口,等待调试客户端(如pychrome)连接。通过连接该端口并成功获取标签页信息,即可确认调试模式已启用。 异常处理: 我们捕获了所有异常,因为任何异常(如连接拒绝、连接超时等)都意味着无法连接到调试端口。 注意:如果浏览器正在运行但未启用调试模式,那么连接调试端口会失败。 参考文献: 关于pychrome的使用,可以参考其官方文档:https://github.com/fate0/pychrome §§相关问题§§ 1. 如何启动Chrome浏览器的调试模式? 2. 如何在Python中控制Chrome浏览器进行自动化操作? 3. 除了pychrome,还有哪些Python库可以用于控制Chrome浏览器? </think>要检测浏览器是否启用调试模式(Debug 模式),可以通过 `pychrome.Browser` 尝试连接浏览器的调试端口并检查响应。以下是具体方法和代码实现: ### 检测 Debug 模式是否启用的方法 ```python import pychrome import requests def is_debug_mode_enabled(port=9222): """ 检测浏览器调试模式是否已启用 :param port: 调试端口号(默认9222) :return: bool - 是否启用调试模式 """ try: # 方法1:使用 HTTP 请求检查调试接口 response = requests.get(f"http://127.0.0.1:{port}/json/version", timeout=1) if response.status_code == 200: return True # 方法2:使用 pychrome 尝试连接(备用) browser = pychrome.Browser(url=f"http://127.0.0.1:{port}") tabs = browser.list_tab() return len(tabs) > 0 except (requests.ConnectionError, pychrome.exceptions.PyChromeException): return False ``` ### 使用说明 1. **检测原理**: - Chrome/Firefox 启用调试模式时会暴露调试接口 - 访问 `/json/version` 端点(DevTools 协议标准接口) - 返回 200 状态码表示调试模式已启用 2. **执行流程**: ```mermaid graph TD A[开始检测] --> B{HTTP 请求<br>/json/version} B -->|200响应| C[返回 True] B -->|连接失败| D[pychrome 连接] D -->|获取标签页成功| C D -->|异常| E[返回 False] ``` 3. **示例调用**: ```python if is_debug_mode_enabled(): print("✅ 调试模式已启用") else: print("❌ 调试模式未启用,请检查浏览器启动参数") ``` ### 调试模式启用要求 浏览器启动时必须添加调试参数: ```bash # Chrome 示例(Windows) chrome.exe --remote-debugging-port=9222 --user-data-dir=C:\temp\debug-profile # Firefox 示例 firefox.exe --start-debugger-server 9222 ``` > **注意事项**: > 1. 确保端口未被防火墙阻止 > 2. 浏览器启动时只能有一个实例使用该端口 > 3. 使用 `timeout` 参数避免长时间阻塞(尤其是当浏览器未运行时) 这种方法参考了 DevTools 协议的实现原理[^1],通过标准化接口实现浏览器兼容性(Chrome/Firefox 均适用)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值