Когда мое приложение запускается, я хочу, чтобы оно динамически создавало sitemap.txt. Для этого у меня должен быть домен веб-сайта, который различается для слотов разработки и производства.
Есть ли способ получить это в Main()? Я думаю, что логически это должно быть известно системе. Но у Blazor есть только NavigationManager
, и эта услуга, похоже, доступна только в контексте страницы.
Если нет, я могу поместить значение в одноэлементный сервис при загрузке первой страницы, а затем создать файлы с помощью BackgroundService
. Спрашиваю здесь, чтобы избежать всего этого.
Обновление: Спецификация sitemap.txt находится здесь (вместе со спецификацией sitemap.xml).
@devlincarnate Эти комментарии заставляют меня думать, что это невозможно.
«Есть ли способ получить это в Main()?» — Короче говоря, нет — потому что Main
можно настроить на запуск до получения любого HTTP-запроса.
«Я думаю, что логически это должно быть известно системе». Напротив: у системы нет возможности узнать, каковы ваши привязки HTTP (и привязки также могут меняться во время выполнения).
Как вы планируете обрабатывать последующие входящие запросы с заголовком Host:
, отличным от первого запроса?
Я делаю это как задачи сборки и генерирую файлы, необходимые приложению. Это также разделяет проблему: приложение обрабатывает входящие запросы пользователей, а сборка генерирует статический файл sitemap.xml для сканеров. В качестве альтернативы, если он должен быть динамическим на лету, вы можете сделать sitemap.xml маршрутом с помощью [AllowAnonymous]
, подключить его через routes.MapRoute(name: "Sitemap",url: "sitemap.xml"
и кэшировать результат.
@Дай, я не подумал о проблеме Host:
. Нужно ли мне создавать отдельный файл sitemap.txt для каждого файла? Я могу сделать, как предлагает @JeremyThompson, и иметь для него контроллер (да, кэшированный), если мне нужно это сделать.
@DavidThielen Признаюсь, я не знаю, что такое sitemap.txt
- старая функция XML Maps Site Maps из (неосновной) ASP.NET последний раз была задокументирована в 2014 и, похоже, не имеет отношения к ASP.NET Core. .
@JeremyThompson в настоящее время я создаю физический файл в корневой папке. Если есть изменение, которое добавляет/удаляет файл (происходит 10–20 раз в день), я устанавливаю флаг, а затем в фоновой службе (запускается каждые 5 минут) он восстанавливает физический файл. Это лучший способ справиться с этим? Регенерация занимает меньше секунды.
@DavidThielen Зачем что-то записывать на диск? Почему вы не можете сохранить это в памяти?
@Dai sitemap.txt похож на sitemap.xml, но это всего лишь URL-адрес в каждой строке. Сканер Google поддерживает его, и он идентичен файлу sitemap.xml без элемента datetime последнего обновления для каждого файла.
@Дай, я могу сохранить это в памяти, но зачем?
@DavidThielen В безопасных производственных средах лучше всего полностью запретить любому веб-приложению запись в любой общедоступный / доступный через Интернет каталог, потому что именно так вас взломают (например, сохранение загруженного l33tshell.php
файла). Конечно, вы можете сохранить текстовый файл в недоступный каталог и использовать действие контроллера для чтения и возврата файла через FileResult
(например).
@ Дай, хорошая мысль. Если вы напишете все это в качестве ответа, буду рад выбрать его.
Похоже, вы двое все уладили.
@DavidThielen Я сейчас разговариваю по телефону - я смогу написать это, вероятно, в течение часа.
@Дай, спасибо, твои ответы всегда великолепны. И я предполагаю, что другие зададутся этим же вопросом. Несколько «Хостов:» тоже были очень хорошим моментом, поскольку мое приложение принимает company.domain.com
, где company
— это название различных организаций, а затем возвращает подмножество соответствующих страниц. Итак, каждому из них нужны sitemap.txt
и robots.txt
. Это обсуждение было очень полезным.
«твои ответы всегда великолепны» — предвзятость выбора: это только потому, что старые злые модераторы удаляют мои меместатические дерьмовые посты 😺
Ваше веб-приложение работает как несколько экземпляров? либо в сценарии «одна машина-несколько-w3wp» (также известном как «веб-сад»), либо на нескольких отдельных машинах/виртуальных машинах (например, несколько экземпляров Azure AppServices) – с общим хранилищем или без него?
@Dai Я масштабировал его до двух экземпляров на сервере приложений Azure.
Сам сервер не знает о своем доменном имени, поскольку доступ к нему осуществляется только по его IP-адресу. Причина, по которой вы можете видеть имя домена во время запроса, заключается в том, что оно отправляется вместе с запросом или во внешнем интерфейсе, потому что браузер знает его.
Вы можете посмотреть builder.Environment
и загрузить имя домена для текущей среды из файла конфигурации.
Вы также можете указать точку sitemap.txt
на контроллере и генерировать ее каждый раз, когда он запрашивается, но в зависимости от размера вашего веб-сайта это может занять слишком много времени. Плюсом этого является то, что ему не нужно записывать данные в вашу файловую систему.
Этот вопрос похож на ваш? Если да, то комментарии могут быть полезны.