我正在构建Chrome应用。我想使用Polymer构建UI。我喜欢它们在example web app in the docs中显示的侧面导航:左侧导航栏中的项目可以更改主窗口中的内容。
我正在努力解决Chrome应用程序的限制问题。应用程序面临严格的内容安全策略(CSP),禁止使用eval,内联脚本和window.history
操作。
我在过去的几个小时里取得了一些进展,但遇到了很多问题。从他们的演示代码开始,我可以让应用程序呈现侧面导航栏而不是内容卡。我使用的是vulcanize
和crisper
,但仍无法使其正常运行。如果它不是404(如果我导入它们,为什么要加载文件?),那就是可疑"拒绝将字符串评估为Javascript"警告似乎与Polymer库本身看似无关紧要的行var noop = Function();
有关。
是否有人知道他们可以指向我的基础知识,Chrome应用程序友好的这种架构示例?它似乎非常基本,但它证明是困难的。
答案 0 :(得分:2)
首先,Chrome应用不支持window.history
系列API。因此,他们用于路由的<app-location>
标记不起作用,因为它依赖于位置并显然利用window.history
API。相反,我删除了该标签,并以某种方式成功地使用数据绑定作为路由。以下是my-app.html
的相关部分。更改的主要内容是删除<app-location>
(为了清楚起见,我在这里留下了评论),并将selected
数据绑定属性从[[page]]
更改为{{page}}
。花括号允许双向绑定。我相信必须允许<iron-selector>
元素将page
变量发送到<iron-pages>
元素。
<!-- <app-location route="{{route}}"></app-location> -->
<app-route
route="{{page}}"
data="{{routeData}}"
tail="{{subroute}}"></app-route>
<app-drawer-layout fullbleed>
<!-- Drawer content -->
<app-drawer>
<app-toolbar>Menu</app-toolbar>
<iron-selector selected="{{page}}" attr-for-selected="name" class="drawer-list" role="navigation">
<a name="view1" >View One</a>
<a name="view2" >View Two</a>
<a name="view3" >View Three</a>
<a name="new-view" href="/new-view">New View</a>
</iron-selector>
</app-drawer>
<!-- Main content -->
<app-header-layout has-scrolling-region>
<app-header condenses reveals effects="waterfall">
<app-toolbar>
<paper-icon-button icon="menu" drawer-toggle></paper-icon-button>
<div title>My App</div>
</app-toolbar>
</app-header>
<iron-pages role="main" selected="{{page}}" attr-for-selected="name">
<my-view1 name="view1"></my-view1>
<my-view2 name="view2"></my-view2>
<my-view3 name="view3"></my-view3>
<my-new-view name="new-view"></my-new-view>
</iron-pages>
</app-header-layout>
</app-drawer-layout>
在下面显示的vulcanize
和crisper
流程之后,这允许在加载为Chrome应用时显示导航栏。但是,页面本身(由<iron-pages>
控制)不会加载。这是因为演示通过动态执行HTML导入来尝试用户友好。由于路径问题(以及可能的网址加载限制 - 我不确定),这会混淆Chrome应用。相反,我们将手动导入它们。这将使vulcanize
发挥其魔力。将以下行添加到src/my-app.html
<link rel="import" href="my-view1.html">
<link rel="import" href="my-view2.html">
<link rel="import" href="my-view3.html">
<link rel="import" href="my-new-view.html">
最后,从observer: '_pageChanged'
的脚本部分删除_pageChanged
和srv/my-app.html
函数。
我们越来越近了。
Chrome Apps具有严格的内容安全策略,可阻止内联脚本(即<script>
标记中的脚本)的执行。 Polymer大量使用内联脚本,因此框架作者提供了一种解决此问题的工具。
vulcanize遍历HTML导入语句以尝试减少网络负载。 crisper提取所有内联脚本并将其添加到具有<script>
属性的单个src
标记中,以便在Chrome应用中执行。以下行将现有的index.html
替换为Chrome应用的一个安全保护。 (注意替换,所以请确保先复制原始index.html
。)
vulcanize --inline-scripts --inline-css index.html | crisper --html index.html --js index.js
现在我们有index.html
没有可以呈现为Chrome应用的任何内联脚本。截至2016-07-30,仍存在两个问题。第一个是Polymer尝试注册服务工作者。打开index.js
并移除serviceWorker.register
电话。其次,在_boundEffect
中找到index.js
的定义。出于某种原因,Chrome应用认为var noop = Function();
需要eval
,并且它不会执行它。将此行替换为var noop = () => {}
。这基本上是相同的,但由于某些原因Chrome Apps允许它。
完成所有这些操作后,在Chrome应用中加载index.html
并演示。
好哇。