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 正确呈现数据的代码由其他函数生成。

与问题相关的文件:

我想将数据从 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 已经传递给外部脚本并且可以被程序访问。故事的结局。我希望它清楚,如果有人需要更多细节 - 让我知道。