vscode webview - 将大量 json 数据从 webview 传递到外部 js
vscode webview - passing huge json data from webview to external js
我编写了 vscode 扩展程序,并使用 webview 来显示文本。
文本存储在 json 文件中 - 这是一个巨大的文件,并且有很多文本。
当鼠标悬停在 webview 上时,该文本中的某些词需要出现弹出窗口 window。
单词和弹出信息存储在 json 中。例如:
{
wordA:{
popupText: "text"
//... and other properties
},
wordA:{
popupText: "another text"
//... and other properties
}
// .... and many many other data
}
我想将此 json 数据从 webview 传递到外部 js 以便能够对其进行管理。由于安全政策,我不能只从 javascript 文件加载 json - 而且我不想破坏安全政策。
HTML 正确呈现数据的代码由其他函数生成。
与问题相关的文件:
- ActivationFile - 推送激活方法并将 webview.ts 的引用传递给 vscode。
- webview.ts 文件 - 具有正确显示我想要呈现的内容和文本信息所需的所有功能
- myScript.js 文件 - 加载到 webview.ts
我想将数据从 webview.ts 传递到 myScript.js
///WebView.ts file
private _getHtmlForWebview(webview: vscode.Webview) {
const scriptPathOnDisk = vscode.Uri.joinPath(this._extensionUri, 'myScript.js');
const scriptUri = (scriptPathOnDisk).with({ 'scheme': 'vscode-resource' });
const jsonPath = fs.readFileSync(path.join(__dirname, 'jsonFile.json'), 'utf8');
const data = JSON.parse(jsonPath);
return `<!DOCTYPE html>
<html lang="en">
<head>
<some html stuff>...
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; style-src ${webview.cspSource}; img-src ${webview.cspSource} https:; script-src 'nonce-${nonce}';">
</head>
<body>
<some html stuff which is generated automatically by other functions of the program>
<for presenting text from json, put them into divs, spans and give them proper ids>
<which will let the javascript manage those divs and spans>...
<script nonce="${nonce}" src="${scriptUri}" type="text/javascript"></script>
</body>
</html>`;
}
nonce由webview.ts
中的函数生成
我尝试在将 myScript 加载到 html
之前添加脚本标签
<script nonce="${nonce}" type="text/javascript">
const jsonData = ${data};
</script>
<script nonce="${nonce}" src="${scriptUri}" type="text/javascript"></script>
但无法在 myScript 中访问数据。
console.log(jsonData.wordA.popupText)
显示错误,json范围内不存在数据
console.log(window.jsonData.wordA.popupText)
显示未定义
我看到了一些针对 React、Angular、Vue 等的解决方案,但这是简单的 webview,我在这里不需要任何大框架,据我所知,它们在这里不起作用。
我也看到了类似 acquireVsCodeApi()
的东西,但我错过了一些东西,我不知道如何设置它。
我解决了我的具体情况。
重点是了解我通过分离文件实际做了什么。
ActivationFile 已注册扩展方法并传递对 webview.ts 文件中函数的引用。
在文档中没有传递 - 所有都在一个文件中完成 - 所以实际上我的名字 'webview.ts' 具有误导性,因为它仍然是扩展名,而不是 webview。
在我的 webview.ts 文件中 post 消息(在创建 webview 的同一函数中)
currentPanel.webview.postMessage({command:"dajaJsonCommand", data:dataJson});
在 myScript.js 中,我将所有内容都包装在 DOMContentLoaded 事件中,然后按照文档并为来自扩展的消息设置事件侦听器。:
document.addEventListener('DOMContentLoaded', (function () {
let dataVariable;
window.addEventListener('message', event => {
const message = event.data; // The JSON data our extension sent
switch (message.command) {
case 'dajaJsonCommand':
dataVariable = message.data;
break;
}
});
然后 json 已经传递给外部脚本并且可以被程序访问。故事的结局。我希望它清楚,如果有人需要更多细节 - 让我知道。
我编写了 vscode 扩展程序,并使用 webview 来显示文本。 文本存储在 json 文件中 - 这是一个巨大的文件,并且有很多文本。 当鼠标悬停在 webview 上时,该文本中的某些词需要出现弹出窗口 window。 单词和弹出信息存储在 json 中。例如:
{
wordA:{
popupText: "text"
//... and other properties
},
wordA:{
popupText: "another text"
//... and other properties
}
// .... and many many other data
}
我想将此 json 数据从 webview 传递到外部 js 以便能够对其进行管理。由于安全政策,我不能只从 javascript 文件加载 json - 而且我不想破坏安全政策。
HTML 正确呈现数据的代码由其他函数生成。
与问题相关的文件:
- ActivationFile - 推送激活方法并将 webview.ts 的引用传递给 vscode。
- webview.ts 文件 - 具有正确显示我想要呈现的内容和文本信息所需的所有功能
- myScript.js 文件 - 加载到 webview.ts
我想将数据从 webview.ts 传递到 myScript.js
///WebView.ts file
private _getHtmlForWebview(webview: vscode.Webview) {
const scriptPathOnDisk = vscode.Uri.joinPath(this._extensionUri, 'myScript.js');
const scriptUri = (scriptPathOnDisk).with({ 'scheme': 'vscode-resource' });
const jsonPath = fs.readFileSync(path.join(__dirname, 'jsonFile.json'), 'utf8');
const data = JSON.parse(jsonPath);
return `<!DOCTYPE html>
<html lang="en">
<head>
<some html stuff>...
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; style-src ${webview.cspSource}; img-src ${webview.cspSource} https:; script-src 'nonce-${nonce}';">
</head>
<body>
<some html stuff which is generated automatically by other functions of the program>
<for presenting text from json, put them into divs, spans and give them proper ids>
<which will let the javascript manage those divs and spans>...
<script nonce="${nonce}" src="${scriptUri}" type="text/javascript"></script>
</body>
</html>`;
}
nonce由webview.ts
中的函数生成我尝试在将 myScript 加载到 html
之前添加脚本标签<script nonce="${nonce}" type="text/javascript">
const jsonData = ${data};
</script>
<script nonce="${nonce}" src="${scriptUri}" type="text/javascript"></script>
但无法在 myScript 中访问数据。
console.log(jsonData.wordA.popupText)
显示错误,json范围内不存在数据
console.log(window.jsonData.wordA.popupText)
显示未定义
我看到了一些针对 React、Angular、Vue 等的解决方案,但这是简单的 webview,我在这里不需要任何大框架,据我所知,它们在这里不起作用。
我也看到了类似 acquireVsCodeApi()
的东西,但我错过了一些东西,我不知道如何设置它。
我解决了我的具体情况。 重点是了解我通过分离文件实际做了什么。 ActivationFile 已注册扩展方法并传递对 webview.ts 文件中函数的引用。 在文档中没有传递 - 所有都在一个文件中完成 - 所以实际上我的名字 'webview.ts' 具有误导性,因为它仍然是扩展名,而不是 webview。
在我的 webview.ts 文件中 post 消息(在创建 webview 的同一函数中)
currentPanel.webview.postMessage({command:"dajaJsonCommand", data:dataJson});
在 myScript.js 中,我将所有内容都包装在 DOMContentLoaded 事件中,然后按照文档并为来自扩展的消息设置事件侦听器。:
document.addEventListener('DOMContentLoaded', (function () {
let dataVariable;
window.addEventListener('message', event => {
const message = event.data; // The JSON data our extension sent
switch (message.command) {
case 'dajaJsonCommand':
dataVariable = message.data;
break;
}
});
然后 json 已经传递给外部脚本并且可以被程序访问。故事的结局。我希望它清楚,如果有人需要更多细节 - 让我知道。