【问题标题】:Backbone Routes with pushState on are not working when you refresh page刷新页面时,启用 pushState 的主干路由不起作用
【发布时间】:2013-10-01 19:37:29
【问题描述】:

我有一个简单的路由器:

Erin.Router = Backbone.Router.extend({
    initialize: function() {
        Backbone.history.start({pushState: true});
    },
    routes: {
        '' : 'index',
        'project/:img' :'project',
    },
    index: function() {
        var galleryView = new Erin.GalleryView();
    },
    project: function(img) {
        console.log(img);
    }
}); 

Erin.GalleryView 的模板是(认为那里可能有问题):

<script type="text/template" id="gallery-grid">
        <a href="/project/<%= id %>">
            <img src="<%= thumbnail %>" />
            <span class="desc">
                <div class="desc-wrap">
                    <p class="title"><%= title %></p>
                    <p class="client"><%= client %></p>
                </div>
            </span>
        </a>
    </script>

GalleryView 和 GalleryItem 代码。

Erin.GalleryItem = Backbone.View.extend({
    tagName: 'div',
    className: 'project-container',
    //Grab the template html
    template: _.template($('#gallery-grid').html()),
    //Set up the render function
    render: function() {
        //What is the $el in this case?
        this.$el.html(this.template(this.model.toJSON()));
        return this;
    }
});

Erin.GalleryView = Backbone.View.extend({
    el: '#projects',
    initialize: function() {
        //create new collection
        this.col = new Erin.Gallery();
        //Listen to all events on collection
        //Call Render on it
        this.listenTo(this.col,'all',this.render);
        //Fetch data
        this.col.fetch();
    },
    render: function() {
        //Get reference to the view object
        var that = this;
        //Empty div
        this.$el.empty();
        //For each model in the collection
        _.each(this.col.models, function(model){
            //call the renderItem method
            that.renderItem(model);
        },this);
    },
    renderItem: function(model) {
        //create a new single item view
        var itemView = new Erin.GalleryItem({
            model:model
        });
        //Append items to to element, in this case "#projects"
        this.$el.append(itemView.render().el);  
    }
});

那我准备好文件了

$(function() {
    var router = new Erin.Router();
    $('#projects').on('click', 'a[href ^="/"]', function(e){
        e.preventDefault();
        router.navigate($(this).attr('href'),{trigger: true});
    });
});

当您加载页面并单击#project 部分中的链接之一时,一切都会正常运行,但是如果您刷新该页面,我会收到一个中断页面的错误。

从控制台:

Uncaught SyntaxError: Unexpected token < js/jquery.js:1
Uncaught SyntaxError: Unexpected token < js/underscore-min.js:1
Uncaught SyntaxError: Unexpected token < js/backbone.js:1
Uncaught SyntaxError: Unexpected token < erin.js:1

它还声明了以下内容:

Resource interpreted as Script but transferred with MIME type text/html: "http://localhost:8888/project/js/backbone.js". 

对于文档头部的所有链接和脚本。

似乎都指向 index.html 文件的第一行。因此,如果我单击一个链接,它将控制我从我的数据中查找的 img id,如果我刷新页面或输入该链接,我会收到上述错误。我是否正确地认为我应该能够保存链接domain.com/project/coolthing 并在有人访问该页面时进行这项工作。我错过了什么吗?实现了一些奇怪的东西?朝正确方向轻推将不胜感激。

谢谢。

【问题讨论】:

  • 能否添加 GalleryView 的代码?至少是加载模板的部分?
  • @providencemac 在顶部添加了该内容。希望这会有所帮助
  • 具体在哪里添加路由器解析的东西,我不知道!

标签: javascript backbone.js backbone-routing


【解决方案1】:

您的服务器端有问题。您可能已经完成了一半。

看起来您已正确配置服务器以在 any 命中时发送您的应用 HTML,但您的资产(js、css)除外。

问题在于您的主 HTML,其中您的 JS 文件是用相对路径引用的。当您在 pushState 将 URL 更新为 /project/1 后重新加载时,基本 URL 将变为 /project/

即。你有

<script src="js/backbone.js"></script>

什么时候应该有

<script src="/js/backbone.js"></script>

因此,当浏览器尝试加载backbone.js 时,它没有找到它(/project/js/backbone.js 不存在),并点击了传递应用程序 HTML 的服务器包(因此导致&lt; 阻塞的解析错误)。

我的解释可能不是很清楚,这里已经很晚了,但我相信你会明白的!

【讨论】:

  • 如此简单,但就是这样。非常感谢。当我有能力的时候,我会给你赏金。
  • 不客气。最简单的错误总是最难追查!
【解决方案2】:

问题在于您在模板中使用的href。骨干路由器正在监视站点 URL 的 hash 部分的更改,该部分是 # 符号之后的内容。

所以你的href应该是:&lt;a href="/#project/&lt;%= id %&gt;"&gt;(注意“项目”之前的#

以这种方式,您甚至根本不需要点击处理程序,路由器会自动捕获哈希更改事件并相应地进行路由。

【讨论】:

  • 抱歉回复晚了,但这仍然不能解决我遇到的错误问题。如果我没记错的话,应该启用 pushstate,这样我就不必拥有哈希值。有人可以去 ..../projects/someid 并获取正确的信息。
【解决方案3】:

thibauts'providencemac's 的评估都是正确的。要么不使用 pushState 并使用散列链接,要么在服务器中设置重写规则以发送静态数据。

最初加载时会加载此 url -

http://localhost:8888

像你的静态网址一样明智的网址是沿着这个

http://localhost:8888/js/backbone.js

真正的问题是当您使用 pushState 并访问链接时。您的浏览器网址变为。像这样 -

http://localhost:8888/project/some_img_id

现在,当您尝试重新加载页面时,索引文件会从此 url 获取 -

http://localhost:8888/project/your_default.file   [index.html]

您的服务器无法找到并默认索引文件位于

http://localhost:8888/your_default.file

当浏览器尝试访问静态数据时,它再次默认为索引文件

http://localhost:8888/project/js/backbone.js

这就是错误的原因。因为它发现 '

Uncaught SyntaxError: Unexpected token < js/jquery.js:1

这个错误导致它试图解析的文件是backbone.js 一个javascript,但是它得到了你的index.html

Resource interpreted as Script but transferred with MIME type text/html: "http://localhost:8888/project/js/backbone.js".

【讨论】:

  • 也感谢您的解释,非常有帮助!如果我能平分赏金,我会的。
  • 哈哈。没必要。接受蒂博,因为他确实发现了您错过的问题(为什么会出错)。普罗维登斯马克的回答告诉了另一点(出了什么问题)。我只是简单地把这两个放在一起,然后说这一切都出了什么问题。
猜你喜欢
  • 1970-01-01
  • 2019-02-24
  • 1970-01-01
  • 1970-01-01
  • 2021-06-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多