0

我有一个简单的扩展,它使用VS Code 的 webview api从我的扩展生成的服务器加载内容。它使用指向以下内容的 iframe 来执行此操作localhost

import * as vscode from 'vscode';
import * as express from 'express';

const PORT = 3000;

export function activate(context: vscode.ExtensionContext) {

    // Spawn simple server
    const app = express();
    app.get('/', (_req, res) => res.send('Hello VS Code!'));
    app.listen(PORT)

    context.subscriptions.push(
        vscode.commands.registerCommand('myExtension.startPreview', () => {
            const panel = vscode.window.createWebviewPanel('myExtension.preview', 'Preview', vscode.ViewColumn.One,
                {
                    enableScripts: true
                });

            panel.webview.html = `<!DOCTYPE html>
            <html lang="en"">
            <head>
                <meta charset="UTF-8">
                <title>Preview</title>
                <style>
                    html { width: 100%; height: 100%; min-height: 100%; display: flex; }
                    body { flex: 1; display: flex; }
                    iframe { flex: 1; border: none; background: white; }
                </style>
            </head>
            <body>
                <iframe src="http://localhost:${PORT}"></iframe>
            </body>
            </html>`
        }));
}

当扩展程序在本地运行时,这工作正常,但是当我尝试在远程工作区中运行我的扩展程序时,iframe 是空的:

在远程工作区中清空 localhost iframe

为什么会发生这种情况,我该如何解决?

4

1 回答 1

0

在远程工作区的 web 视图中使用 localhost 时,这是预期的。根本原因是 webviews 加载在用户的本地机器上,而您的扩展程序正在远程机器上运行:

webview中的localhost解析到本地机器

有两种可能的解决方法:

将您的扩展标记为UI 扩展,以便它始终在本地计算机上运行。

如果您的扩展不需要从工作区读取文件或使用仅与工作区一起安装的脚本/工具,则可以将扩展设置为 UI 扩展。UI 扩展在用户的本地机器上运行,因此它产生的服务器可以使用 localhost 访问

只需添加"extensionKind": "ui"到您的扩展程序package.json即可。

为您的 webview 配置 portMapping

VS Code 端口映射 API 允许您将 webview 中使用的 localhost 端口映射到运行扩展程序的机器上的任意端口。如果您的扩展程序远程运行,这甚至可以工作。

端口映射 API 是在 VS Code 1.34 中添加的。要使用它,请在创建 webview 面板时传入一个portMapping对象:

const panel = vscode.window.createWebviewPanel('myExtension.preview', 'Preview', vscode.ViewColumn.One,
    {
        enableScripts: true,
        // This maps localhost:3000 in the webview to the express server port on the remote host.
        portMapping: [
            { webviewPort: PORT, extensionHostPort: PORT}
        ]
    });

如果您的 webview 出于任何原因使用 localhost,最好进行设置portMapping,以便它可以在任何地方正确运行。在实践中,您还应该考虑随机化您的服务器运行在哪个端口上。使用端口映射,您无需为此更改 webview 的 html:

{ webviewPort: 3000, extensionHostPort: RANDOM_PORT_SERVER_WAS_STARTED_ON }

有关详细信息,请参阅 VS Code 文档

于 2019-05-04T00:36:25.477 回答