[英]How to solve “violate CSP directive: ”default-src 'self'" in Angular 8?
We have an Angular 8 single page web app deployed on the customer server.我们在客户服务器上部署了一个 Angular 8 单页 web 应用程序。 They set one of the CSP directive to: default-src 'self'.
他们将 CSP 指令之一设置为:default-src 'self'。 We build the Angular app using
ng build --prod
like any other Angular applications.我们使用
ng build --prod
Angular 应用程序,就像任何其他 Angular 应用程序一样。 After deploying, we get this error:部署后,我们收到此错误:
main-es2015.47b2dcf92b39651610c0.js:1 Refused to apply inline style because it violates the following Content Security Policy directive: "default-src 'self'". Either the 'unsafe-inline' keyword, a hash ('sha256-47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU='), or a nonce ('nonce-...') is required to enable inline execution. Note also that 'style-src' was not explicitly set, so 'default-src' is used as a fallback.
Look into the html
code on the browser, I see something like this:在浏览器上查看
html
代码,我看到如下内容:
As you can see, Angular actually use tag <style>
to serve the css (please correct me if I'm wrong).如您所见,Angular 实际上使用标签
<style>
来为 css 服务(如果我错了,请纠正我)。 This violates the CSP directive mentioned in the question.这违反了问题中提到的 CSP 指令。
After searching around, I think Angular/React is quite bad at handling this issue, those frameworks are not built with CSP in mind.在搜索之后,我认为 Angular/React 在处理这个问题方面相当糟糕,这些框架没有考虑到 CSP。 You can check out Angular github page, there is an open issue for this.
您可以查看 Angular github 页面,这是一个未解决的问题。 Now I'm searching for a solution to overcome this, of course changing CSP policy is not an option because the customers don't want to.
现在我正在寻找一种解决方案来克服这个问题,当然改变 CSP 策略不是一种选择,因为客户不想这样做。
How can I tell Angular not to use tag <style>
in production to serve css?如何告诉 Angular 不要在生产中使用标签
<style>
来服务 css? I think to make it works we need to set Angular in a way that it will load the css files, and then use styles in those files instead of injecting <style>
into html
which causes CSP issue. I think to make it works we need to set Angular in a way that it will load the css files, and then use styles in those files instead of injecting
<style>
into html
which causes CSP issue.
Edit 1 : Our project is using scss
.编辑 1 :我们的项目正在使用
scss
。
Edit 2 : After searching around, I have found out that Angular will inject your component's styles into the DOM by using <style>
element.编辑 2 :搜索后,我发现 Angular 将使用
<style>
元素将组件的 styles 注入 DOM。 As shown here:如此处所示:
Now I have an idea, because for each compinent's style will be injeced into the DOM through <style>
element, we can prevent this from happening by bundling all component's style .scss
file into a single style.scss
file.现在我有了一个想法,因为每个组件的样式都会通过
<style>
元素注入到 DOM 中,我们可以通过将所有组件的样式.scss
文件捆绑到单个style.scss
文件中来防止这种情况发生。 From the image above you can see that we always have an empty <style>
element, so if this works, we will endup with only one <style>
element and a <link>
element that link to our global style scss
file.从上图中你可以看到我们总是有一个空的
<style>
元素,所以如果这样的话,我们最终将只有一个<style>
元素和一个链接到我们的全局样式scss
文件的<link>
元素。 We can have multiple way to remove that empty <style>
element before the page got rendered by the browser.在页面被浏览器渲染之前,我们可以有多种方法来删除那个空的
<style>
元素。
Now I'm stuck at configuring custom webpack to make this happen.现在我坚持配置自定义 webpack 来实现这一点。 We cant use
ng eject
to get the webpack.config.js
file since Angular CLI 6. I've been using Angular CLI 8 so the only way for me to add custom configuration into Webpack is to use custom-webpack
npm. We cant use
ng eject
to get the webpack.config.js
file since Angular CLI 6. I've been using Angular CLI 8 so the only way for me to add custom configuration into Webpack is to use custom-webpack
npm. I cant find a good config file that has the same output as my desire, please help if you know how to config webpack to bundle all component's styles scss
files in Angular into a global scss
file. I cant find a good config file that has the same output as my desire, please help if you know how to config webpack to bundle all component's styles
scss
files in Angular into a global scss
file.
I think this can be an acceptable answer for my question:我认为这对于我的问题来说是一个可以接受的答案:
First of all, my recommendation is stay away from using styleUrls
.首先,我的建议是远离使用
styleUrls
。 Angular will inject styles of your component into the DOM using <style>
element. Angular 将使用
<style>
元素将组件的 styles 注入到 DOM 中。 Secondly, if it's possible, you should know / ask for the CSP policy on the deployment server/environment.其次,如果可能的话,您应该了解/询问部署服务器/环境上的 CSP 策略。 What I have been doing to resolve the issue (my project is reletively small with just a couple dozen of components):
我一直在做什么来解决这个问题(我的项目相对较小,只有几十个组件):
Copy (one by one) relative link of components, put them into angular.json
, in styles
attribute.复制(一个一个)组件的相关链接,将它们放入
angular.json
,在styles
属性中。 This is because Angular will bundle all styles in this attribute as a single css/scss
file.这是因为 Angular 会将此属性中的所有 styles 捆绑为单个
css/scss
文件。 I copy one by one because the css/scss
file was designed to work with Angular View Encapsulation in the first place.我一个一个地复制,因为
css/scss
文件首先设计为与 Angular 视图封装一起使用。 Gathering all of them into one place might introduct unexpected issue, this will break the UI.将它们全部集中到一个地方可能会引入意想不到的问题,这会破坏 UI。 Whenever copy a component style and put into
styles
, I check if the UI breaks because of that.每当复制组件样式并放入
styles
时,我都会检查 UI 是否因此而中断。 This will help me narrow down the root cause if such issue happens.如果发生此类问题,这将帮助我缩小根本原因。
For each component, after copy its component style file's relative path into styles
, I remove styleUrls
in @Component
.对于每个组件,在将其组件样式文件的相对路径复制到
styles
,我删除了@Component
中的styleUrls
。 This prevents Angular from injecting <style>
into the DOM.这可以防止 Angular 将
<style>
注入 DOM。
Caveats:注意事项:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.