【问题标题】:vscode webview - passing huge json data from webview to external jsvscode webview - 将大量 json 数据从 webview 传递到外部 js
【发布时间】:2021-09-14 09:49:52
【问题描述】:

我编写 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() 的东西,但我错过了一些东西,我不知道如何在我的情况下设置它。

【问题讨论】:

  • 在 webview 加载后尝试以message 发送 json。
  • @User863 使用这种方法,我可以将数据从 acivationFile.ts 发送到 webview.ts,我需要将这些数据从 webview.ts 发送到外部 javascript myScript.js

标签: javascript json visual-studio-code webview security-policy


【解决方案1】:

我解决了我的具体情况。 重点是通过分离文件来了解我实际上做了什么。 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已经传给外部脚本,程序可以访问了。故事的结局。我希望它清楚,如果有人需要更多详细信息 - 请告诉我。

【讨论】:

    猜你喜欢
    • 2011-06-21
    • 2021-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-20
    • 2015-11-27
    • 2014-03-28
    • 1970-01-01
    相关资源
    最近更新 更多