【问题标题】:How can I route to / serve static files with page.js and Apache?如何使用 page.js 和 Apache 路由到/提供静态文件?
【发布时间】:2023-10-01 01:07:02
【问题描述】:

我有一个使用page.js 设置的路由器,用于路由索引页面('/')、项目页面('/projects/<projectId>/')和静态(图像)文件。基本上,它看起来像这样:

JavaScript

init: function () {
    page.base('/');
    // IndexPage
    page('', function (context, next) {
        displayIndexPage();
    });
    // ProjectPage
    page('projects/:project', function (context, next) {
        displayProjectPage();
    });
    // image files
    page(/^.+\.(jpg|png|gif|bmp)$/, function (context, next) {
        window.location = '/' + context.path;
    });
    // Exit the middleware
    page();
}

在我的/projects/ 文件夹中,我有一个.htaccess 文件,其中包含以下内容:

狂欢

    Options +FollowSymLinks
    RewriteEngine On
    # html5 pushstate (history) support
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_URI} !index
    RewriteRule ^.*$ ../index.html [QSA,L,NE]

路由通常工作正常。当我导航到静态图像文件时,.htaccess 将我从我的单页应用程序中删除,静态文件出现在屏幕上。但是,当我在浏览器中导航回来时,我不会重新进入我的应用程序; URL 更改,但没有导航,图像文件仍保留在屏幕上。再多的弹出或推送状态都无法让我回到我的应用程序中。

我不完全确定我在这里问的是正确的问题;不确定这是否与提供静态文件和路由单页应用程序一样多...我会对任何允许 page.js 在popState 上取回的答案感到满意。

编辑:我正在从我的RewriteRule 中免除文件,因为我需要在我的应用程序呈现的页面中提供它们。但是,当访问者单击呈现页面中的图像时,我希望浏览器仅显示该图像,不带任何标记。

【问题讨论】:

  • 另外,我的围栏代码块做错了什么?为什么语法高亮在这里不起作用?
  • 哦,糟糕,SO 不支持受保护的代码块。我猜太习惯了GH。谢谢@ariful-haque。
  • 您到Page.js 的链接没有显示,因为您忘记在前面添加https://
  • 您可以发布您正在使用的图片网址的示例吗?不确定您是否需要图像路由,因为如果图像文件路径退出,apache 不会绕过 index.html 直接提供它(RewriteCond %{REQUEST_FILENAME} !-f
  • @ChrisGunawardena 这是该站点:transmote.com 单击任何项​​目,然后单击任何图像,然后浏览器导航返回查看问题。路由图像文件的目的是明确地脱离应用程序并允许 Apache 直接为它们提供服务;如果没有路由到应用程序出口,Apache 永远不会知道任何改变,因为一切都在 page.js 中发生。

标签: javascript .htaccess url-routing single-page-application static-files


【解决方案1】:

如果我了解您想要的最终结果,可以通过包含覆盖整个窗口的图像的简单叠加来完成。然后捕获 popstate 事件并删除覆盖。 JQuery 不是必需的,只是为了简洁。

jsfiddle 注意:您的浏览器 URL 不会改变,因为小提琴位于 iframe 中。

编辑:* 将原点设置为 null,因此请检查 jsfiddle 以获取工作示例。

var url = 'http://indianapublicmedia.org/stateimpact/files/2013/01/apple-image-300x300.jpg';

$('.image').click(function () {
    $('body').append('<div id="overlay"><img src="' + url + '"></div>').appendTo('body');
    history.pushState(null, null, 'http://*.com/imageURL');
});

window.onpopstate = function(){
    $('#overlay').remove();
};
#overlay {
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: 100;
    position: fixed;
    background: white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<body>Some content here
    <img src="http://indianapublicmedia.org/stateimpact/files/2013/01/apple-image-300x300.jpg" class='image'>
</body>

【讨论】:

  • 谢谢——我可能最终会做这样的事情(类似于上面@Abhilash S Hebbar 推荐的内容),但我更愿意让浏览器原生处理图像......跨度>
【解决方案2】:

点击图片链接时你的期望是什么?

在为图像路由时,不要更改位置,而是尝试对图像执行其他操作。通过 AJAX 加载它并按照您的期望将其附加到某个元素左右。

// image files
page(/^.+\.(jpg|png|gif|bmp)$/, function (context, next) {
    // Culprit
    // window.location = '/' + context.path;

    showImage('/' + context.path);
});

编辑

为图片使用非 page.js 链接以允许浏览器直接处理它。 Example

由于服务器端路由,jsfiddle 链接无法正常工作,但如果您将其复制回服务器,它将起作用。

【讨论】:

  • 我的期望是图像文件以浏览器的原生图像显示格式显示在浏览器中。发生这种情况,但用户现在不再在 page.js 应用程序中。向后导航,URL 应该 被 Apache 拾取,并且应该有一个重定向回 /index.html,page.js 应该在此处重新启动并相应地路由查看器。相反,导航事件只是被吞没了,除了 URL 没有任何变化。
  • 好的,在这种情况下,对于 jpg,不要使用 page.js。使用图像的直接链接。现在 page.js 更改了一次 url,您的 javascript 再次更改它,将 2 个 url 添加到历史记录中。当您从图像页面单击返回时,您会转到再次重定向到图像的页面 js 路由,并且您处于该循环中。
  • 我认为你是对的!我认为window.location() 调用会退出 page.js,但您所描述的内容听起来合乎逻辑。我只需要弄清楚如何为给定的 URL 模式完全避免 page.js 路由。有什么小窍门吗?我现在无法测试。另外,如果您可以编辑您对此效果的答案,这样我可以接受它,如果它有效,那将是很棒的。
  • 我认为这个例子不适用于我的情况;它之所以有效,是因为它导航到 page.base() 设置之外的 URL/域,但我的图像与其余路由位于同一域中。
最近更新 更多