Я обслуживаю Vue SPA из веб-приложения Azure. Логики на стороне сервера нет (или в любом случае не имеет отношения к этой проблеме).
Я использую Vue Router в режиме истории HTML5. Это действительно хорошо работает. Единственная проблема заключается в том, что происходит, когда пользователь пытается получить доступ к представлению внутри приложения с «прямым» URL-адресом, например https://my.app.com/contacts. Как и ожидалось, это дает ошибку 404 Not Found.
Обходной путь хорошо известен: используйте перезапись URL, чтобы направить такие запросы в корень приложения: / или /index.html.
Вот что я пытаюсь сделать. Для веб-приложений Azure это можно сделать с помощью правил перезаписи в файле web.config. Мой Web.config выглядит так:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="Handle History Mode and custom 404/500" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="/" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
Это взято прямо из документации для Vue Router, здесь.
Когда я сейчас захожу на сайт, я получаю пустую страницу. Используя консоль разработчика (в Chrome) и проверив вкладку сети, я обнаружил, что все запросы теперь возвращают содержимое index.html, включая файлы сценариев и файлы css.
Так что переписывание явно работает, только многовато.
Проблема, по-видимому, заключается в (отрицаемых) условиях IsFile и IsDirectory. Они используют серверную переменную REQUEST_FILENAME. С этой страницы я поймите, что это должен быть отображенный путь в файловой системе сервера.
Поскольку все запросы перезаписываются, это должно происходить из-за того, что условия не могут распознать пути как допустимые пути к файлам или каталогам.
Изменить: я использовал отслеживание неудачных запросов для отладки перезаписи URL и узнал кое-что еще. Оказывается, при запуске модуля перезаписи переменная REQUEST_FILENAME
неверна.
В веб-приложении Azure корень содержимого находится в D:\site\wwwroot
. В этой папке находится папка wwwroot моего приложения. Некоторые поисковые запросы показывают, что это соответствует ожиданиям. Кроме того, сопоставление работает правильно - без включенной перезаписи URL-адреса путь URL-адреса, например /img/logo.png
, вернет статический файл в D:\site\wwwroot\wwwroot\img\logo.png
.
Но когда запускается модуль перезаписи URL, REQUEST_FILENAME
будет иметь значение D:\site\wwwroot\img\logo.png
. Этот файл не существует, поэтому условие IsFile
не выполняется.
Тогда возникает вопрос: почему модуль перезаписи URL и поставщик статических файлов расходятся во мнениях относительно сопоставления пути?