backbonejs 演示案例不能很好地与堆栈片段中添加的本地存储一起使用
backbonejs demo case can't work well with localstorage added in stack snippet
我正在尝试使用堆栈片段工具将实时演示案例嵌入到我的 post 中。但是我发现当我把localstorage功能添加到demo case中时,它不能很好地工作。
所以我将我的问题简化为基本的 backbone 情况,以强调上述本地存储问题。
如果我去掉localstorage流程,demo可以运行很好地通过,但是如果添加了localstorage,那么它就不能很好地工作了。来自控制台的错误消息说
Failed to read the 'localStorage' property from 'Window': The document is sandboxed and lacks the 'allow-same-origin' flag.
有什么想法吗?
// A simple case
var Daymodel = Backbone.Model.extend({
defaults : {
day: 1,
}
});
var DayCollection = Backbone.Collection.extend({
model: Daymodel,
localStorage: new Backbone.LocalStorage("test-simple")
});
// The view for each day panel
var DayView = Backbone.View.extend({
tagName:"div",
template: _.template( $('#eachday-template').html() ),
initialize: function() {
this.listenTo(this.model, "change", this.render);
},
render: function(){
this.$el.html(this.template(this.model.toJSON()));
return this;
}
});
// The view for the entire application
var AppView = Backbone.View.extend({
el: $('#todoapp'),
events: {
"click #add-firebase":"addToLocalhost"
},
initialize: function() {
this.daylist = this.$("#container"); // the daylist to append to
this.listenTo(this.collection, 'add', this.addOne);
this.collection.fetch();
},
addOne: function(todo) {
var view = new DayView({model:todo});
this.daylist.append(view.render().el);
},
addToLocalhost: function(){
this.collection.create({
day : this.collection.length + 1,
});
}
});
// Create a function to kick off our BackboneFire app
function init() {
// The data we are syncing from our remote Firebase database
var collection = new DayCollection();
var app = new AppView({ collection: collection });
}
// When the document is ready, call the init function
$(function() {
init();
});
<div id="todoapp">
<div id="container"></div>
<button id="add-firebase">Add to Localstorage</button>
</div>
<script type="text/template" id="eachday-template">
<h3 class="which-day"> day <%= day %></h3>
<ul id="todo-list"></ul>
</script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js">
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.3.3/backbone-min.js">
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone-localstorage.js/1.1.16/backbone.localStorage-min.js">
</script>
答案在您收到的错误消息中:"The document is sandboxed"。您不能乱用 localStorage,因为它是所有沙盒 iframe
文档的受限功能 ,除非 明确解除限制。
如果您查看页面源代码,您会看到 iframe
和 sandbox
属性选项。
<iframe name="d62428c9-4eba-3156-6ef7-8815d959a281"
sandbox="allow-modals allow-scripts"
class="snippet-box-edit" frameborder="0">
有关详细信息,请参阅 Play safely in sandboxed IFrames。
The framed document is loaded into a unique origin, which means that
all same-origin checks will fail; unique origins match no other
origins ever, not even themselves. Among other impacts, this means
that the document has no access to data stored in any origin's cookies
or any other storage mechanisms (DOM storage, Indexed DB, etc.).
[...]
With the exception of plugins, each of these restrictions can be
lifted by adding a flag to the sandbox attribute’s value. Sandboxed
documents can never run plugins, as plugins are unsandboxed native
code, but everything else is fair game:
allow-forms
allows form submission.
allow-popups
allows popups (window.open()
, showModalDialog()
, target="_blank"
, etc.).
allow-pointer-lock
allows (surprise!) pointer lock.
allow-same-origin
allows the document to maintain its origin; pages loaded from https://example.com/
will retain access to that
origin's data.
allow-scripts
allows JavaScript execution, and also allows features to trigger automatically (as they'd be trivial to implement
via JavaScript).
allow-top-navigation
allows the document to break out of the frame by navigating the top-level window.
对于allow-modals
,Add allow-modals to the sandbox of Stack Snippets给出了更多的细节:
Chrome blocks modal dialogs such as alert
, confirm
and prompt
in
sandboxed iframes unless allow-modals
is set. This behavior became the
default as of Chrome 46 and Opera 34.
我正在尝试使用堆栈片段工具将实时演示案例嵌入到我的 post 中。但是我发现当我把localstorage功能添加到demo case中时,它不能很好地工作。
所以我将我的问题简化为基本的 backbone 情况,以强调上述本地存储问题。
如果我去掉localstorage流程,demo可以运行很好地通过,但是如果添加了localstorage,那么它就不能很好地工作了。来自控制台的错误消息说
Failed to read the 'localStorage' property from 'Window': The document is sandboxed and lacks the 'allow-same-origin' flag.
有什么想法吗?
// A simple case
var Daymodel = Backbone.Model.extend({
defaults : {
day: 1,
}
});
var DayCollection = Backbone.Collection.extend({
model: Daymodel,
localStorage: new Backbone.LocalStorage("test-simple")
});
// The view for each day panel
var DayView = Backbone.View.extend({
tagName:"div",
template: _.template( $('#eachday-template').html() ),
initialize: function() {
this.listenTo(this.model, "change", this.render);
},
render: function(){
this.$el.html(this.template(this.model.toJSON()));
return this;
}
});
// The view for the entire application
var AppView = Backbone.View.extend({
el: $('#todoapp'),
events: {
"click #add-firebase":"addToLocalhost"
},
initialize: function() {
this.daylist = this.$("#container"); // the daylist to append to
this.listenTo(this.collection, 'add', this.addOne);
this.collection.fetch();
},
addOne: function(todo) {
var view = new DayView({model:todo});
this.daylist.append(view.render().el);
},
addToLocalhost: function(){
this.collection.create({
day : this.collection.length + 1,
});
}
});
// Create a function to kick off our BackboneFire app
function init() {
// The data we are syncing from our remote Firebase database
var collection = new DayCollection();
var app = new AppView({ collection: collection });
}
// When the document is ready, call the init function
$(function() {
init();
});
<div id="todoapp">
<div id="container"></div>
<button id="add-firebase">Add to Localstorage</button>
</div>
<script type="text/template" id="eachday-template">
<h3 class="which-day"> day <%= day %></h3>
<ul id="todo-list"></ul>
</script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js">
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.3.3/backbone-min.js">
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone-localstorage.js/1.1.16/backbone.localStorage-min.js">
</script>
答案在您收到的错误消息中:"The document is sandboxed"。您不能乱用 localStorage,因为它是所有沙盒 iframe
文档的受限功能 ,除非 明确解除限制。
如果您查看页面源代码,您会看到 iframe
和 sandbox
属性选项。
<iframe name="d62428c9-4eba-3156-6ef7-8815d959a281"
sandbox="allow-modals allow-scripts"
class="snippet-box-edit" frameborder="0">
有关详细信息,请参阅 Play safely in sandboxed IFrames。
The framed document is loaded into a unique origin, which means that all same-origin checks will fail; unique origins match no other origins ever, not even themselves. Among other impacts, this means that the document has no access to data stored in any origin's cookies or any other storage mechanisms (DOM storage, Indexed DB, etc.).
[...]
With the exception of plugins, each of these restrictions can be lifted by adding a flag to the sandbox attribute’s value. Sandboxed documents can never run plugins, as plugins are unsandboxed native code, but everything else is fair game:
allow-forms
allows form submission.allow-popups
allows popups (window.open()
,showModalDialog()
,target="_blank"
, etc.).allow-pointer-lock
allows (surprise!) pointer lock.allow-same-origin
allows the document to maintain its origin; pages loaded fromhttps://example.com/
will retain access to that origin's data.allow-scripts
allows JavaScript execution, and also allows features to trigger automatically (as they'd be trivial to implement via JavaScript).allow-top-navigation
allows the document to break out of the frame by navigating the top-level window.
对于allow-modals
,Add allow-modals to the sandbox of Stack Snippets给出了更多的细节:
Chrome blocks modal dialogs such as
alert
,confirm
andprompt
in sandboxed iframes unlessallow-modals
is set. This behavior became the default as of Chrome 46 and Opera 34.