我为其他页面测试了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://stackoverflow.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://stackoverflow.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}\"');")