当连接到远程工作区时,为什么 localhost 在我的 VS Code 的 Web 视图中不起作用?
Why does localhost not work inside my VS Code's webviews when connected to remote workspaces?
我有一个简单的扩展程序,它使用 VS Code's webview api 从我的扩展程序生成的服务器加载内容。它使用指向 localhost
:
的 iframe 执行此操作
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>`
}));
}
当扩展在本地运行时这很好用,但是当我尝试 运行 我在 remote workspace 中的扩展时,iframe 是空的:
为什么会发生这种情况,我该如何解决?
在远程工作区的 web 视图中使用 localhost 时,这是预期的。根本原因是 webviews 加载在用户的本地机器上,而您的扩展在远程机器上 运行ning:
对此有两种可能的修复方法:
将您的扩展标记为 UI Extension,这样它在本地机器上总是 运行。
如果扩展不需要从工作区读取文件或使用只能随工作区一起安装的 scripts/tools,则可以将扩展设置为 UI 扩展。 UI 扩展在用户的本地机器上 运行,所以它生成的服务器可以使用 localhost
访问
只需将 "extensionKind": "ui"
添加到您的分机的 package.json
即可。
为您的 webview 配置端口映射
VS Code 端口映射 API 允许您将 webview 中使用的本地主机端口映射到扩展名为 运行ning 的机器上的任意端口。如果您的分机是 运行ning 远程,这甚至可以工作。
VS Code 1.34 中添加了端口映射 API。要使用它,请在创建 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 出于任何原因使用本地主机,最好设置 portMapping
以便它可以在任何地方正确地 运行。实际上,您还应该考虑随机选择服务器 运行 所在的端口。使用端口映射,您无需为此更改 webview 的 html:
{ webviewPort: 3000, extensionHostPort: RANDOM_PORT_SERVER_WAS_STARTED_ON }
我有一个简单的扩展程序,它使用 VS Code's webview api 从我的扩展程序生成的服务器加载内容。它使用指向 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>`
}));
}
当扩展在本地运行时这很好用,但是当我尝试 运行 我在 remote workspace 中的扩展时,iframe 是空的:
为什么会发生这种情况,我该如何解决?
在远程工作区的 web 视图中使用 localhost 时,这是预期的。根本原因是 webviews 加载在用户的本地机器上,而您的扩展在远程机器上 运行ning:
对此有两种可能的修复方法:
将您的扩展标记为 UI Extension,这样它在本地机器上总是 运行。
如果扩展不需要从工作区读取文件或使用只能随工作区一起安装的 scripts/tools,则可以将扩展设置为 UI 扩展。 UI 扩展在用户的本地机器上 运行,所以它生成的服务器可以使用 localhost
访问只需将 "extensionKind": "ui"
添加到您的分机的 package.json
即可。
为您的 webview 配置端口映射
VS Code 端口映射 API 允许您将 webview 中使用的本地主机端口映射到扩展名为 运行ning 的机器上的任意端口。如果您的分机是 运行ning 远程,这甚至可以工作。
VS Code 1.34 中添加了端口映射 API。要使用它,请在创建 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 出于任何原因使用本地主机,最好设置 portMapping
以便它可以在任何地方正确地 运行。实际上,您还应该考虑随机选择服务器 运行 所在的端口。使用端口映射,您无需为此更改 webview 的 html:
{ webviewPort: 3000, extensionHostPort: RANDOM_PORT_SERVER_WAS_STARTED_ON }