- Electron版本: 12.0.0(实际上,除了beta/夜间测试版之外,我测试了很多其他版本)
- 操作系统: Linux
- 最后已知的正常工作的Electron版本: 无
预期行为
document.cookie: is-paid-user=1
将被打印到控制台。
实际行为
document.cookie:
将被打印到控制台(没有 is-paid-user=1
cookie记录)。
重现方法
在将 web://news.ycombinator.com
更改为 https://news.ycombinator.com 后,问题将消失。
const {app, BrowserWindow, protocol} = require("electron");
const scheme = "web";
protocol.registerSchemesAsPrivileged([{scheme, privileges: {secure: true, standard: true, corsEnabled: true}}]);
app.whenReady().then(() => {
const window = new BrowserWindow();
window.webContents.session.protocol.registerBufferProtocol(scheme, (...[, callback]) => {
callback({mimeType: "text/html", data: Buffer.from("<h5>blank page</h5>")})
})
window.loadURL("web://news.ycombinator.com").then(() => {
window.webContents.openDevTools();
window.webContents.executeJavaScript(`
document.cookie = "is-paid-user=1;expires=Fri, 31 Dec 2021 20:59:59 GMT;domain=.ycombinator.com;path=/";
console.log("document.cookie: ", document.cookie);
`);
});
});
截图
- https协议:
- web/自定义协议:
其他信息
我的理解是,在 registerSchemesAsPrivileged
调用中设置 standard: true
就足以使 document.cookie
在自定义协议上工作。
7条答案
按热度按时间fkvaft9z1#
是否有解决方案?
6l7fqoea2#
在这条线上失败了:https://source.chromium.org/chromium/chromium/src/+/master:net/cookies/cookie_util.cc;l=268;drc=587068ee20325543d40cbd4bf50bed6af51ee23e
因为
将cookie更改为适用于
news.ycombinator.com
的结果是,this check被触发了,因为cookieable方案不包括web
。不幸的是,看起来要在不影响chrome的情况下影响该列表的唯一方法是通过CookieManagerParams.allow_file_scheme_cookies,这将把file:
添加到cookieable方案列表中。没有办法向其中添加任意方案。简而言之,我们不支持自定义协议上的cookie,如果没有相当大的努力,也无法实现。
...而且看起来我之前在这里做过同样的调查:#20940(评论)
我将其更改为功能请求。如果有人想解决这个问题,我很乐意审查PR,但请注意:我会要求你将任何补丁提交给Chromium。
oxcyiej73#
tl;dr 我们不支持自定义协议上的cookies。
这个信息是否在https://www.electronjs.org/docs的某个地方有记录?
6uxekuva4#
我认为不是这样...我不确定在哪里记录会是最好的地方。你想发起一个文档PR吗?
mlmc2os55#
你想发起一个文档PR吗?
还没准备好投入其中。
但是如果文档能更新一下就好了,因为我在提交问题之前已经审阅过了,但接下来的部分误导了我:https://github.com/electron/electron/blame/80f89a34728281cc61cfacd7b682f0227f89a102/docs/api/protocol.md#L101-L104 (注意
cookies
的提及)默认情况下,对于非标准方案,web存储API(localStorage、sessionStorage、webSQL、indexedDB、cookies)是禁用的。因此,一般来说,如果你想注册一个自定义协议来替换
http
协议,你必须将其注册为标准方案。我不确定在哪里记录会更好。
所以也许调整会在引用的段落附近落地。
scyqe7ek6#
遗憾的是,看起来在不修补Chrome的情况下影响该列表的唯一方法是通过CookieManagerParams.allow_file_scheme_cookies,这将向cookieable scheme列表中添加
file:
。目前这是可能的吗?
我遇到了一个依赖于cookies工作的第三方SDK的问题。由于我在使用本地开发服务器,它在开发环境中运行得很好,但我还没有通过file:或自定义协议将其打包到生产状态中运行成功。
我看到的另一个选择是运行本地服务器,即使是在生产环境中,并通过http服务器上传文件,这将不太理想。
xe55xuns7#
大家好!这个问题有什么新进展吗?
像大多数人一样,我也被这个链接:https://github.com/electron/electron/blame/80f89a34728281cc61cfacd7b682f0227f89a102/docs/api/protocol.md#L101-L104 弄得有些困惑。我认为自定义协议的文档应该明确指出不支持cookie。
理想情况下,应该有一些关于如何设置一些常见场景的示例。例如,在我的案例中,我试图打包一个使用React编写的单页应用程序,该应用程序访问远程后端。后端具有适当的CORS和CSRF(期望客户端设置一个带有从cookie读取的内容的头部)。
根据我在网上找到的一些提示,我能够使用
webRequest.onHeadersReceived
和webRequest.onBeforeSendHeaders
调整应用程序中的CORS后端设置。因此,使用file://
协议的所有GET请求都能正常工作。经过一些调查,从文档中我发现,添加一个自定义协议并将其注册为标准协议将允许我完全替换http
协议......但在几次尝试后,我意识到无法设置cookie。即使从控制台运行,结果也是:
Uncaught (in promise) DOMException: An unknown error occurred while writing the cookie.
因此,我决定寻找一个bug(我认为这是一个bug,因为文档明确指出,作为标准注册的自定义协议可以实现替换http协议的目的)。
除了定义自己的自定义方案之外,我还尝试拦截http协议
protocol.interceptFileProtocol('http', handler)
,它似乎起作用了,使用的处理程序与我在protocol.registerFileProtocol('app', handler)
中使用的完全相同。这种方法有潜在的问题吗?