跳到主要内容

为什么要转换网页资源地址并限制本地资源根目录?

结论​

网页视图不能直接用磁盘路径加载脚本和图片。要用 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 的查询参数。地址会出现在页面和日志里。