Reputation: 3101
I'm writing a vsc extenion that uses a webview. The extension itself works fine but the JS and CSS in my webview are not being loaded.
I keep getting errors in the webview console like:
VM102 main.js:12 Refused to load the stylesheet 'vscode-resource://file///full/disc/path/to/vsc-extension/resources/css/webview-package.css' because it violates the following Content Security Policy directive: "style-src nonce-LSAOCrvSSPay9prF40mc5JyRJ9BzFUKR". Note that 'style-src-elem' was not explicitly set, so 'style-src' is used as a fallback.
(anonymous) @ VM102 main.js:12
VM102 main.js:12 Refused to load the script 'vscode-resource://file///full/disc/path/to/vsc-extension/resources/js/webview-package.js' because it violates the following Content Security Policy directive: "script-src nonce-LSAOCrvSSPay9prF40mc5JyRJ9BzFUKR". Note that 'script-src-elem' was not explicitly set, so 'script-src' is used as a fallback.
I have the following CSP meta tag in my template for the web view:
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; script-src nonce-${nonce}; style-src nonce-${nonce};">
This is my webview template:
`<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; script-src nonce-${nonce}; style-src nonce-${nonce};">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>${packageName}</title>
<link href="${cssUri}" nonce="${nonce}" rel="stylesheet" type="text/css">
</head>
<body>
<h1 id="${EXT}__name">${packageName}</h1>
<script nonce="${nonce}" src="${scriptUri}"></script>
</body>
</html>`
The paths to the resources are created as shown in the webview docs:
const scriptPath = vscode.Uri.file(
path.join(extensionPath, FS_FOLDER_RESOURCES, FS_FOLDER_JS, FS_WEBVIEW_PACKAGE_JS)
);
const cssPath = vscode.Uri.file(
path.join(extensionPath, FS_FOLDER_RESOURCES, FS_FOLDER_CSS, FS_WEBVIEW_PACKAGE_CSS)
)
I have experimented with various CSP formats and keep having errors, my code is just not loading. It is blocked due to the CSP, but I don't understand why. I followed all the instructions here:
https://code.visualstudio.com/api/extension-guides/webview#content-security-policy
and looked a lots of example CSP tags linked to here:
https://github.com/microsoft/vscode/issues/79340
But still nothing is ever loaded.
Here is my css:
html,
body {
background: red;
}
h1 {
background: blue;
}
The JS looks like this:
// This script will be run within the webview itself
// It cannot access the main VS Code APIs directly.
(function () {
console.log('### test);
alert('### test');
}());
But I don't think they are the problem as they are blocked due to CSP.
Upvotes: 4
Views: 2762
Reputation: 49
For those that arrive here trying to figure out why their css and js load fine in the webview during debugging (F5), but then don't show after packaging (vsce package) I'd like to help.
I was placing my .css and .js files in a folder that held my class implementing webview. Something like /src/components/a/folder/js/some.js and /src/components/a/folder/css/style.css.
But things got mixed up during packaging. After lots of arguing with webpack I moved everything to a media folder off root (like the examples). And the problems cleared up.
My final home was /media/js/some.js and /medida/css/style.css.
Upvotes: 1
Reputation: 344
I had a similar situation to you. #
The extensionPath
is a property of ExtensionContext
, You should access the ExtensionContext
of your extension first to get extensionPath
. In the docs ExtensionContext
,
An instance of an ExtensionContext is provided as the first parameter to the activate-call of an extension.
By default, the activate-call of your extension is function activate(context)
. You can access ExtensionContext
using the parameter context
in this scope.
So if you want to get the path of extension, you should use context.extensionPath
.
And I highly recommend adding security policy in the <meta>
tag and a local resource contorl in localResourceRoots
like below
vscode.ViewColumn.One,
{
// Enable scripts in the webview
enableScripts: true,
// Only allow the webview to access resources in our extension's media directory
localResourceRoots: [vscode.Uri.file(path.join(context.extensionPath, 'media'))]
}
);
HTML tag
<meta
http-equiv="Content-Security-Policy"
content="default-src 'none'; img-src ${webview.cspSource} https:; script-src ${webview.cspSource}; style-src ${webview.cspSource};"
/>
Security Policy is not activated when you don't write <meta http-equiv="Content-Security-Policy">
, it means to allow all resources, but it could occur security issues.
Upvotes: 8