Chrome 无法获取 localStorage
Posted
技术标签:
【中文标题】Chrome 无法获取 localStorage【英文标题】:Chrome is unable to get localStorage 【发布时间】:2021-08-04 02:18:45 【问题描述】:我目前正在尝试制作一个脚本,您可以使用该脚本使用您的令牌自动登录不和谐。然而,当我尝试做window.localStorage.setItem("token", "value");
它只是sais
selenium.common.exceptions.javascriptException: Message: javascript error: Cannot read property 'setItem' of undefined
。
那么如果window.localStorage
未定义,我该如何更改它并访问本地存储?
如果有帮助,这是我的完整代码:
from selenium import webdriver
token = input("Enter User Token:\n -> ")
driver = webdriver.Chrome()
driver.get("https://www.discord.com/login")
driver.execute_script(f"window.localStorage.setItem('token', 'token');")
driver.refresh()
编辑: 我的最终代码可在this GitHub Repo 上找到。 (https://github.com/RealMoondancer/DiscordTokenLogin)
【问题讨论】:
总是将完整的错误消息(从单词“Traceback”开始)作为文本(不是截图,不是链接到外部门户)有问题(不是评论)。还有其他有用的信息。 脚本可能正在使用变量“localStorage”并且它已被初始化。尝试设置。使用 var localStorage = window.localStorage;然后 localStorage.setItem(... 我在其他页面上测试过,似乎只有这个页面没有window.localStorage
。或者它可能出于安全原因阻止它。
如果有人想要我的最终代码,我在这里上传:github.com/RealMoondancer/DiscordTokenLogin
【参考方案1】:
我为其他页面测试了window.localStorage
,只有这个页面没有。
在我找到的所有 JavaScript 文件中检查了单词 localStorage
之后
https://discord.com/assets/43c944f57ecd3f83e53c.js
行
delete window.localStorage
删除这个对象 - 这会产生问题。
我认为他们这样做是出于安全原因。
delete
之前还有
r=window.localStorage
这可能意味着他们将其分配给变量 r
以保持访问权限,但此变量对我不起作用。可能他们稍后将其分配给其他变量,但代码被混淆了,我无法识别他们分配它的位置。
编辑:
在谷歌上查看后,我发现了类似的问题
Discord window.localStorage is undefined. How to get access to the localStorage on Discord page?
答案显示如何重新创建对localStorage
的访问权限。
// If we create an <iframe> and connect it to our document, its
// contentWindow property will return a new Window object with
// a freshly created `localStorage` property. Once we obtain the
// property descriptor, we can disconnect the <iframe> and let it
// be collected — the getter function itself doesn’t depend on
// anything from its origin realm to work**.
function getLocalStoragePropertyDescriptor()
const iframe = document.createElement('iframe');
document.head.append(iframe);
const pd = Object.getOwnPropertyDescriptor(iframe.contentWindow, 'localStorage');
iframe.remove();
return pd;
// We have several options for how to use the property descriptor
// once we have it. The simplest is to just redefine it:
Object.defineProperty(window, 'localStorage', getLocalStoragePropertyDescriptor());
window.localStorage.heeeeey; // yr old friend is bak
// You can also use any function application tool, like `bind` or `call`
// or `apply`. If you hold onto a reference to the object somehow, it
// won’t matter if the global property gets deleted again, either.
const localStorage = getLocalStoragePropertyDescriptor().get.call(window);
当我在 JavaScript 控制台中测试它时,这对我有用(对于页面 discord.com
)
编辑:
最少的工作代码。
from selenium import webdriver
import time
def test1(driver, url, token='abc'):
print('[test1] url:', url)
driver.get(url)
time.sleep(1)
try:
driver.execute_script(f"window.localStorage.setItem('token', 'token');")
driver.refresh()
print('[test1] get token:', driver.execute_script(f"return window.localStorage.getItem('token');") )
except Exception as ex:
print('[Exception]', ex)
def test2(driver, url, token='abc'):
recreate_localStorage_script = '''
const iframe = document.createElement('iframe');
document.head.append(iframe);
const pd = Object.getOwnPropertyDescriptor(iframe.contentWindow, 'localStorage');
iframe.remove();
Object.defineProperty(window, 'localStorage', pd);
'''
print('[test2] url:', url)
driver.get(url)
time.sleep(1)
try:
driver.execute_script(recreate_localStorage_script)
driver.execute_script(f"window.localStorage.setItem('token', 'token');")
driver.refresh()
driver.execute_script(recreate_localStorage_script)
print('[test2] get token:', driver.execute_script(f"return window.localStorage.getItem('token');") )
except Exception as ex:
print('[Exception]', ex)
if __name__ == '__main__':
token = 'abc'
driver = webdriver.Chrome()
#driver = webdriver.Firefox() # raise error when you try to use localStorage: "SecurityError: The operation is insecure."
# selenium.common.exceptions.JavascriptException: Message: SecurityError: The operation is insecure.
test1(driver, "https://httpbin.org/get", token) # OK
test1(driver, "https://***.com", token) # OK if it sleeps few (milli)seconds
test1(driver, "https://discord.com/login", token) # ERROR
test2(driver, "https://httpbin.org/get", token) # OK
test2(driver, "https://***.com", token) # OK
test2(driver, "https://discord.com/login", token) # OK
顺便说一句:
当我尝试在 Firefox
中使用 localStorage
时,它会引发错误
selenium.common.exceptions.JavascriptException:
Message: SecurityError: The operation is insecure.
它可能需要其他东西来解决这个问题。
编辑:
对于其他访问者:正如@Moondancer 在评论中提到的那样,如果token
像这样在" "
中,它就可以工作
driver.execute_script(f"window.localStorage.setItem('token', '\"token\"');")
【讨论】:
我添加了用于测试问题的最小工作示例。 顺便说一句,如果您想登录不和谐,您必须将driver.execute_script(f"window.localStorage.setItem('token', 'token');")
更改为driver.execute_script(f"window.localStorage.setItem('token', '\"token\"');")
,因为该值必须在“”中。
你做到了吗?你用 localStorage 登录了吗?
是的,我已经使用 localStorage 成功登录。只需将令牌添加为值 sorroundet by "" 并作为键使用 token
并刷新站点。
我将此信息添加到回答中,以便其他访问者看到它。以上是关于Chrome 无法获取 localStorage的主要内容,如果未能解决你的问题,请参考以下文章
无法使用 chrome.bluetoothLowEnergy 从 iOS 外围设备获取服务