0

我编写 vscode 扩展代码,并使用 webview 来呈现文本。文本存储在 json 文件中 - 这是一个巨大的文件,并且有很多文本。当鼠标悬停在 web 视图上时,该文本中的某些单词需要出现弹出窗口。单词和弹出信息存储在 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)显示错误,范围内不存在 jsonData

console.log(window.jsonData.wordA.popupText)显示未定义

我看到了一些针对 React、Angular、Vue 等的解决方案,但这是简单的 webview,我在这里不需要任何大框架,据我所知,它们在这里不起作用。

我也看到了类似的acquireVsCodeApi()东西,但我错过了一些东西,我不知道如何在我的情况下设置它。

4

1 回答 1

0

我解决了我的具体情况。重点是通过分离文件来了解我实际上做了什么。ActivationFile 已注册扩展方法并传递对 webview.ts 文件中函数的引用。在文档中没有传递-所有内容都在一个文件中完成-所以实际上我的'webview.ts'名称具有误导性,因为它仍然是扩展名,而不是webview。

在我的 webview.ts 文件中我发布消息(在创建 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 已经被传递给外部脚本并且可以被程序访问。故事的结局。我希望它清楚,如果有人需要更多细节 - 让我知道。

于 2021-09-15T10:53:36.907 回答