Серверная часть включает в себя в качестве метода шаблонов / макета

Я делаю веб-сайт для компании, и я хотел использовать что-то вроде страниц макета ASP.NET MVC для динамической загрузки контента в макет, но используемый хостинг-провайдер не поддерживает ASP.NET. Я предположил, что они поддерживают Node.js, потому что они сказали, что единственное, что они не поддерживают, это.NET, поэтому я использовал библиотеку шаблонов под названием Embedded JavaScript Templates ( http://ejs.co/) с Express.js, но потом выяснил, что хостинг-провайдер также не поддерживает Node.

Включения на стороне сервера определенно поддерживаются, но мой вопрос заключается в том, могу ли я использовать их, чтобы взять имя файла из URL-адреса, по которому перемещался пользователь, передать его на стороне сервера, включить в страницу index.html (страницу, которую я пытаюсь использовать как страницы макета) и веб-сервер вводит контент, где находится тег включения? Пока что все примеры, которые я видел для серверной части, показывают имя файла, введенное в виде литерала, например:

<!--#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. Вот JavaScript для загрузки содержимого в файл index.html (/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. Я знаю, что хостинг-провайдер поддерживает это наверняка.

1 ответ

Я нашел решение, которое работает почти так же, как страницы компоновки ASP.NET MVC, что в основном и было тем, о чем я просил в своем первоначальном вопросе, но вместо этого использует серверные включения (SSI). Сначала я должен был определить правильный синтаксис для ввода имени переменной в виртуальный параметр тега include. В моем случае это должно выглядеть так:

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

И это должно быть введено в "страницу макета" (в моем случае, index.html), где вы хотите, чтобы страница "частичного просмотра" появилась. Поэтому, если я введу адрес, такой как https://example.com/physician, сервер переведет "doctor" в "views/physician.html" в качестве локального относительного пути (поскольку каталог views в моем локальном веб-корне находится там, где мой представления сохраняются), и содержимое этого файла будет вставлено в index.html, где находится тег include.

Есть еще один шаг. Я изменил свой файл.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>

RewriteCond с флагом -f сообщает серверу, что если в пути, указанном после RewriteCond, есть файл, то примените RewriteRule после RewriteCond. DOCUMENT_ROOT после RewriteCond необходим, потому что при использовании -f относительные пути не работают.

RewriteRules возвращает страницу на основе пути, который пользователь ввел в ее браузер. Они принимают регулярное выражение, соответствующее пути, введенному пользователем. Первый RewriteRule имеет регулярное выражение.*, Которое соответствует любому пути, введенному пользователем. Но RewriteCond до того, как он сообщает RewriteRule, должен применяться только тогда, когда файл в пути, введенном пользователем, существует в папке представлений на сервере. Если нет, первый RewriteRule не применяется. В противном случае сервер отправит обратно index.html с тегом включения, который будет заменен страницей, введенной пользователем, как описано выше. Окончательный вариант RewriteRule совпадает только с /, иначе невозможно было бы перейти в корень сайта.

На самом деле я поместил несколько условных тегов в мой файл index.html, окружающий тег include:

<!--#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, если файл существует (сообщение переполнения стека)

Другие вопросы по тегам