【问题标题】:Server side includes as a templating/layout technique服务器端包括作为模板/布局技术
【发布时间】:2018-12-11 11:44:49
【问题描述】:

我正在为一家公司做网站,我想使用 ASP.NET MVC 布局页面之类的东西将内容动态加载到布局中,但该公司使用的托管服务提供商不支持 ASP.NET .我以为他们支持 Node.js,因为他们说他们唯一不支持的是 .NET,所以我在 Express.js 中使用了一个名为 Embedded JavaScript Templates (http://ejs.co/) 的模板库,但后来找到了托管服务提供商也不支持Node。

绝对支持服务器端包含,但我的问题是我可以使用它们从用户导航的 url 中获取文件名,将其传递到 index.html 页面中的服务器端包含(我正在尝试的页面用作布局页面)并让 Web 服务器在包含标签所在的位置注入内容?到目前为止,我在服务器端看到的所有示例都包括以文字形式输入的文件名,例如:

<!--#include virtual="physicians.html" -->

而我希望包含的文件由用户导航到该站点时输入的内容来确定。如果它是http://website.com/physicians.html,那么应该在 index.html 文件中加载包含注入位置的“physicians.html”。像这样的东西(显然不起作用):

<!--#include virtual="${REQUEST_URI}" -->

我还尝试将以下内容添加到 .htaccess 文件中(请注意,我知道它不启用服务器端包含。我后来启用了 SSI 并且 SSI 正在工作,但不是按照我想要的方式,如上所述之前):

<ifModule mod_rewrite.c>
  Options +FollowSymLinks
  IndexIgnore */*
  RewriteEngine On
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule (.*) index.html
</ifModule>

这来自http://krasimirtsonev.com/blog/article/deep-dive-into-client-side-routing-navigo-pushstate-hash。我将上面的 .htaccess 配置与他的客户端库 Navigo 和一些 AJAX 一起使用。这是用于将内容加载到 index.html 文件中的 JavaScript(/views 是存储部分视图的位置):

function loadViewContent(viewPath)
{
    $('#main-content').load(viewPath, navSetActive);
}
var root = "http://www.caduceuscorporation.com";
var router = new Navigo(root);
router.on({
    '/': loadViewContent.bind(this, "views/home.html"),
    'index.html': loadViewContent.bind(this, "views/home.html"),
    '/:page': function(params) {
        loadViewContent("views/" + params.page + ".html");
    }
})
.resolve();

它工作得很好,除非我输入了一个无效的文件名,然后它会进入一个无限循环,在自身内部加载 index.html。 .htaccess 配置的作用是,如果路径无效,服务器会发回 index.html 的内容,因此 index.html 会无限循环加载自身。

有没有办法使用服务器端包含根据用户输入的 URL 而不是预先确定的文件来加载内容?或者我需要使用不同的 .htaccess 配置吗?我希望我已经说明了我想要做什么。如果 SSI 或不同的 .htaccess 配置不起作用,我想我可能不得不使用 PHP。我知道托管服务提供商肯定支持这一点。

【问题讨论】:

    标签: .htaccess server-side-includes


    【解决方案1】:

    我找到了一个几乎与 ASP.NET MVC 布局页面一样工作的解决方案,这基本上是我在原始问题中所要求的,但使用服务器端包含 (SSI) 代替。我首先必须弄清楚将变量名称输入到包含标记的虚拟参数中的正确语法。就我而言,它应该如下所示:

    <!--#include virtual="views${REQUEST_URI}.html" -->
    

    它应该被输入到您希望“部分视图”页面出现的“布局页面”(在我的例子中是 index.html)中。因此,如果我输入像https://example.com/physician 这样的地址,服务器会将“physician”转换为“views/physician.html”作为本地相对路径(因为我的本地 Web 根目录中的 views 目录是存储我的视图的位置)并且该文件的内容将被插入到包含标签所在的 index.html 中。

    还有一步。我将 .htaccess 文件修改为如下所示:

    <ifModule mod_rewrite.c>
        RewriteEngine on
        Options +Includes
        AddHandler server-parsed .html 
        IndexIgnore */*
        RewriteCond %{DOCUMENT_ROOT}/views%{REQUEST_URI}.html -f
        RewriteRule .* index.html
        RewriteRule ^/$ index.html
    </ifModule>
    

    带有 -f 标志的 RewriteCond 告诉服务器如果在 RewriteCond 之后列出的路径中有文件,则在 RewriteCond 之后应用 RewriteRule。 RewriteCond 后面的 DOCUMENT_ROOT 是必须的,因为使用 -f 时,相对路径不起作用。

    RewriteRules 根据用户在浏览器中输入的路径返回一个页面。它们采用与用户输入的路径匹配的正则表达式。第一个 RewriteRule 具有正则表达式 .*,它匹配用户输入的任何路径。但是之前的 RewriteCond 告诉 RewriteRule 仅在用户输入的路径中的文件存在于服务器上的 views 文件夹中时才应用。如果不是,则不应用第一个 RewriteRule。否则,服务器将返回 index.html,其中包含标签被用户输入的页面替换,如上所述。最终的 RewriteRule 只匹配 /,否则无法进入网站根目录。

    我实际上在我的 index.html 文件中放入了一些条件标签,包含标签:

    <!--#if expr="${REQUEST_URI} != '/'" -->
    <!--#include virtual="views${REQUEST_URI}.html" -->
    <!--#else -->
    <!--#include virtual="views/home.html" -->
    <!--#endif -->
    

    这样可以在用户进入网站根目录时加载主页,否则用户不输入/home就无法访问主页。

    我使用的资源:

    https://httpd.apache.org/docs/trunk/howto/ssi.html(Apache SSI 教程)

    RewriteRule htaccess if a file exists(堆栈溢出帖子)

    【讨论】:

      猜你喜欢
      • 2011-06-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-19
      • 2011-11-29
      相关资源
      最近更新 更多