-
Notifications
You must be signed in to change notification settings - Fork 66
8 修正云开发控制台
本节将修正云开发控制台功能。
点击 云开发 图标按钮,启动失败。
控制台报错与娴熟错误一致:
Uncaught TypeError: Cannot read property 'isDev' of undefined
点击控制台报错进入相关文件,查看得知 isDev 位于 global.appConfig.isDev
;
在云开发的开发者工具中执行 global.appConfig.isDev
结果为 undefined
,在主界面的开发者工具中执行可以得到以下结果:
{
"isDev": false,
"isBeta": false,
"isGamma": false
}
猜测:点击 云开发 按钮后,新建了一个窗口,但这个窗口与父窗口隔离;
可能的取消隔离方案:
- 创建新窗口时共用实例。
- 能同时获取到新旧窗口,将就窗口数据复制到新窗口。
尝试在 package.nw 下搜索 「云开发」结果有点多( grep -lr '云开发' .
),寻找其他关键字;
在调试器中查看,应该可以根据页面链接寻找 plugin-webview.html
。
根据链接地址搜索 grep -lr 'plugin-webview.html' .
,只有一个 core.wxvpkg。
./core.wxvpkg
解包 core.wxvpkg
解包打包工具:https://gist.github.com/chemzqm/9f2334ca201dc2fbc363fdd757aa2ed4
解包后,在解包出的文件中搜索图标 grep -lr 'plugin-webview.html' .
查找出一个文件:
./284af385b4ef6206861fea66a2452277.js
在 284af385b4ef6206861fea66a2452277.js
文件中:
openWindow(e) {
const t = "pluginid=" + this.props.pluginId;
let i = this.props.webview ? "html/plugin-webview.html?" + t : "html/plugin-window.html?" + t;
if (this.props.searchParams)
for (const e in this.props.searchParams) i += `&${e}=${this.props.searchParams[e]}`;
nw.Window.open(i, this.getWindowOptions(), e => {
if (!e) return void(this.props.onWindowOpenFail && this.props.onWindowOpenFail());
if (this.unmounted) return void e.close(!0);
this.registryId = this.props.registryId, this.child = e, e.on("close", () => {
setTimeout(this.closeWindow.bind(this), 100), this.props.onWindowClose && this.props.onWindowClose(e)
}), e.on("new-win-policy", (e, t, i) => {
console.log(e, t, i), i.forceCurrent()
}), this.props.persistId && this.localizeLocalStorage(e.window.localStorage, this.props.persistId), this.props.onWindowOpen && this.props.onWindowOpen(e), this.registryId && (h.register({
id: this.registryId,
window: e
}), global.windowMap.set(this.registryId, e)), this.props.scriptSource && this.setupWindow(this.props.scriptSource);
e.window.onload = () => {
this.setupWindowFrameTheme(this.props), this.props.webview && this.setupWebview(this.props.url), !1 === this.props.frame && this.setupWindowFrame()
}
})
}
可以看到调用了 nw.Window.open
打开新窗口。
查看相关文档(文档链接),可通过open方法的回调实现共享变量(经尝试设定new_instance
与mixed_context
无效)
在回调函数中添加:
Object.keys(window).forEach(key=>{
if(!e.window[key]){
/*没有就添加*/
try{
e.window[key] = window[key];
}catch(e){
/*部分方法不可修改,会抛异常*/
console.error(e);
}
}
})
测试:
出现了新的表现,云开发工具无限等待,主界面开发工具报 token 错误。
在解包后的 core.wxvpkg 中搜索 invalid token
;
只得到一个结果。
文件中的注释表明这是 websocket 客户端相关的代码块:
/*!
* ws: a node.js websocket client
* Copyright(c) 2011 Einar Otto Stangvik <[email protected]>
* MIT Licensed
*/
使用断点调试,发现 _tokenMap 一直是空的。
相关构造函数:
constructor() {
this._sessionToken = "",
this._tokenMap = {}
}
将构造函数修改为:
constructor() {
this._sessionToken = "",
this._tokenMap = {};
console.warn('====token constructor====')
}
运行,发现云开发与主界面都执行了构造方法,
但是,理论上应该是用来双方进行通信需要的,不应该独自创建;
尝试使用 window 对象做「中间人」存储 token 数据:
constructor() {
if(window.tokenData){
/*有就直接用*/
this._sessionToken = window.tokenData._sessionToken
this._tokenMap = window.tokenData._tokenMap
}else{
/*没有就新建*/
(this._sessionToken = ""), (this._tokenMap = {});
window.tokenData=this;/*新建完要给中间人*/
}
}
打包启动,OK了