Accordion Collapsible 不仅在 Heroku 中工作CSP 问题

问题描述

我面临一个非常奇怪的问题。我实现了一些嵌套的可折叠和简单的可折叠,它们在 localhost 上工作得很好。但在 Heroku 中,我仍然不明白为什么可折叠不能工作。欢迎任何帮助,没有工作可折叠我的网络应用程序会显得混乱:(

哈巴狗布局

doctype html
html(lang='en')
    head
        title= title
        Meta(charset='utf-8')
        Meta(name='viewport',content='width=device-width,initial-scale=1')
        script(src="https://code.jquery.com/jquery-3.5.1.slim.min.js",integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj",crossorigin="anonymous")
        link(rel="stylesheet",href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css",integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZonixN0hoP+VmmDGMN5t9UJ0Z",crossorigin="anonymous")
        script(src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js",integrity="sha384-B4gt1jrGC7Jh4AgTPSdUtOBvfO8shuf57BaghqFfPlYxofvL8/KUEfYiJOMMV+rV",crossorigin="anonymous")
        link(rel='stylesheet',href='/stylesheets/style.css')
    body
    div(class='container-fluid')
      div(class='row')
        div(class='col-sm-2')
          block sidebar
            ul(class='sidebar-nav')
              li
                a(href='/catalog') Home
              li
                a(href='/catalog/resources') All Resources

              li
                a(href='/catalog/bookings') My Bookings
        div(class='col-sm-10')
          block content

可折叠 PUG

extends layout
block content
  -var i=0;
  -var months = ["January","February","march","April","May","June","July","August","September","October","November","December"]
        #accordion.panel-group
        each doc in object
           flex-container(style='background-color:#c7e7fa; justify-content:space-around; position:relative;flex-direction:row;margin-left:20px;margin-right:auto; margin-top:20px; width:45%; ')
            .three(style='text-align:center;margin-left:auto; margin-right:auto; flex: 0 0 40%;')
              h4='' + doc._id.year + '  ' + months[doc._id.month - 1]
              -i++;
            #accordion.panel-group
             .panel-heading
               h4.panel-title
                 a.accordion-toggle(data-toggle='collapse',href='#collapses' + i)
                   h6 See Total Cost
             .panel-collapse.collapse.in(id="collapses" + i)
                .three(style='width:100%; margin-left:auto; margin-right:auto; flex: 0 0 25%;')
                  h5= 'Total Montly Cost:  ' + doc.total_cost_month.toFixed(2)
                                .panel-heading
                                  h4.panel-title
                                    a.accordion-toggle(data-toggle='collapse',href='#collapse'+i)
                                      hr
                                      h6 See All Booking details
                                .panel-collapse.collapse.in(id="collapse"+i)
                                  each booking in doc.bookings_month
                                    flex-container(style='background-color:#a6f1a6; width:100%;')
                                                three.flex-container
                                                    | #[strong Start:] #{moment(booking.date_started).format('DD/MM/YYYY HH:mm')}
                                                three.flex-container
                                                    | #[strong  Finish:] #{moment(booking.date_finished).format('DD/MM/YYYY HH:mm')}
                                                three.flex-container
                                                    | #[strong  Cost:]  #{booking.total_cost.toFixed(2)}
                                                li
        else
            h1 No booking history found
            h3= 'Start booking Now' + "  "
             a(href='/catalog/resources')
              | here:

解决方法

这样就解决了。问题来源于服务器端。特别是来自helmejs,app.use(helmet())。因此,头盔默认会阻止所有内容,例如在 pug 视图中加载的脚本样式表和多媒体链接,以防止 XSS 攻击。所以我们要做的是告诉头盔我们想要将一些链接引用列入白名单,这可能是样式表链接、脚本链接和图像链接等。我们通过在我们的代码 (app.js) 中包含此代码来做到这一点片段。

app.use(helmet({
  contentSecurityPolicy:{
    directives:{
      "default-src":["'self'"],"script-src":["https://code.jquery.com/jquery-3.5.1.slim.min.js","'sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj'","https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js","'sha384-B4gt1jrGC7Jh4AgTPSdUtOBvfO8shuf57BaghqFfPlYxofvL8/KUEfYiJOMMV+rV'"],"style-src": ["'self'","https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css","'unsafe-inline'"],"object-src":["'none'"],},}
}
));

所以头盔是一个我们已经在我们的应用程序中导入的模块。这个模块有一些属性。在我们的问题中,我们关注属性 contentSecurityPolicy,因为我们需要解决一个 CSP 问题。为了放置一些异常,我们将它们添加到 directives 属性中。这些异常是键值对,其中键是将在我们的网络应用程序中加载的内容的类型,值是承载内容的实际链接.所以现在我们将解决解决方案,注意属性的顺序,因为这非常重要。 "default-src":["'self'"] 是默认属性,我们告诉网络应用程序仅从其域 'self' 加载内容。 接下来是 "script-src",这是我们的 jquery 脚本,其哈希值取自我们上面的layoyt,也是使用我们的引导样式表的脚本,这也有它的哈希值。然后是 "style-src" 是实际的引导程序模板,我们添加 'self'(我不太确定 self 是否不是可选的)然后我们使用 "'unsafe-inline'" 这意味着我们的应用程序加载哈希存在于每个特定的哈巴狗模板中。最后 "object-src" 是我们应该分配为 "'none'" 的属性。 所以这就是注意命令的顺序