为什么要转换网页资源地址并限制本地资源根目录?
结论
网页视图不能直接用磁盘路径加载脚本和图片。要用 webview.asWebviewUri 把文件 URI 转成网页能访问的地址,并用 localResourceRoots 声明允许读取的目录。
展开
网页跑在独立来源里,和扩展宿主不是同一个世界。file:// 或裸的绝对路径会被拦掉。
const scriptUri = webview.asWebviewUri(
vscode.Uri.joinPath(context.extensionUri, "media", "main.js")
);
panel.webview.options = {
enableScripts: true,
localResourceRoots: [vscode.Uri.joinPath(context.extensionUri, "media")]
};
HTML 里引用 scriptUri。转换后的地址带有编辑器发给这个网页的来源信息,只有该网页能用。
localResourceRoots 是白名单。默认情况下,网页能读到的本地资源很有限。把整个磁盘根目录放进去,等于让网页能读宿主机文件,不应该这么做。工作区里的图片如果也要展示,再把对应工作区文件夹加进来,而不是加用户主目录。
资源要用 extensionUri 拼接,不要写死开发机上的绝对路径。插件安装后的真实位置在不同系统、不同远程窗口都不一样。
样式里的 VS Code 主题变量不需要本地文件。字体、图标如果来自插件目录,同样要转换。
容易讲错的点
asWebviewUri每次创建网页都要重新生成。把上一份面板的地址缓存进新面板会失效。- 漏配
localResourceRoots时,页面能打开,脚本却 404,控制台里是资源被拒绝。 - 不要把令牌放进资源 URI 的查询参数。地址会出现在页面和日志里。