company_banner

Динамическое создание robots.txt для сайтов ASP.NET Core

Автор оригинала: SCOTT HANSELMAN
  • Перевод

Сейчас я нахожусь в процессе переноса части старых WebForms моего сайта, которые пока работают на голом железе, в ASP.NET Core и службы приложений Azure. В процессе я понял, что хочу убедиться, что мои сайты не индексируются в Google, Яндекс, Bing и в других поисковых системах.


У меня уже есть файл robots.txt, но я хочу, чтобы один служил только для продакшена, а другие — для разработки. Я думал о нескольких способах решить эту проблему. Я мог бы иметь статический файл robots.txt, файл robots-staging.txt и условно скопировать один поверх другого в моем Azure DevOps CI/CD pipeline.


Затем я понял, что самое простое — сделать robots.txt динамичным. Я думал о написании собственного промежуточного ПО, но это казалось хлопотным занятием с большим количеством кода. Я хотел посмотреть, насколько просто это может быть.




  • Можно реализовать это в виде встроенного промежуточного ПО: просто lambda, func и linq в одну строку
  • Можно написать свое собственное промежуточное ПО и сделать множество опций, затем активировать его в окружении env.IsStaging() или другом
  • Можно создать одиночную Razor Page с TegHelpers среды

Последний вариант казался самым простым и означал, что я мог изменить cshtml без полной перекомпиляции, поэтому я создал одиночную Razor Page RobotsTxt.cshtml. Затем я использовал встроенный теговый помощник среды для условной генерации частей файла. Также обратите внимание, что я принудительно указал тип mime как text/plain и не использую страницу Layout, поскольку она должна быть автономной.


@page
@{
    Layout = null;
    this.Response.ContentType = "text/plain";
}
# /robots.txt file for http://www.hanselman.com/
User-agent: *
<environment include="Development,Staging">Disallow: /</environment>
<environment include="Production">Disallow: /blog/private
Disallow: /blog/secret
Disallow: /blog/somethingelse</environment>

Затем я проверяю, правильно ли установлены переменные ASPNETCORE_ENVIRONMENT в моих стэгинг и/или продакшн системах.


ASPNETCORE_ENVIRONMENT=Staging

Я также хочу указать на то, как может выглядеть нечетный интервал и как некоторый текст упирается в TagHelpers. Помните, что тег TagHelper иногда «исчезает» (удаляется), когда он делает свое дело, но пропуски вокруг него остаются. Поэтому я хочу, чтобы в User-agent: * имелась строка, а затем Disallow немедленно появлялся на следующей строке. Хотя исходный код может быть красивее, если он начинается с другой строки, но тогда это будет неправильный файл. Я хочу, чтобы результат был правильным. Это для понимания:


User-agent: *
Disallow: /

Это дает мне файл robots.txt в /robotstxt, но не в /robots.txt. Видите ошибку? Robots.txt — это файл (фальшивый), поэтому мне нужно сопоставить маршрут от запроса на /robots.txt до страницы Razor с именем RobotsTxt.cshtml.


Здесь я добавляю RazorPagesOptions в мой Startup.cs с пользовательским PageRoute, который отображает /robots.txt в /robotstxt. (Я всегда считал этот API раздражающим, так как параметры, по моему мнению, должны быть изменены на («from»,«to»), так что следите за этим, чтобы вы не потратили десять лишних минут, как я только что сделал).


public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc()
        .AddRazorPagesOptions(options =>
    {
        options.Conventions.AddPageRoute("/robotstxt", "/Robots.Txt");
    });
}

И это все! Просто и прозрачно.


Вы также можете добавить кеширование, если хотите, в качестве промежуточного ПО большего размера или даже на странице cshtml, например


context.Response.Headers.Add("Cache-Control", $"max-age=SOMELARGENUMBEROFSECONDS");

но я оставлю эту небольшую оптимизацию в качестве упражнения для вас.


UPDATE: Когда я закончил, я нашел это промежуточное ПО robots.txt и NuGet на GitHub. Я все еще доволен своим кодом и не возражаю против отсутствия внешней зависимости (мне не важна внешняя независимость), но приятно сохранить его для будущих более сложных задач и проектов.


Microsoft
Microsoft — мировой лидер в области ПО и ИТ-услуг

Комментарии 2

    +1
    Как-то все сложно выглядит. Если есть прокси-сервер на фронте, то можно там прописать директиву локейшена, которая отдает нужный robots в зависимости от настроек окружения. Благо у robots только 1 вариант урла может быть, без всяких вариантов.
      0
      А почему бы не написать middleware свой. и отдавать нужный файл в зависимости от запроса, при этом можно обернуть в нугет и получить универсальное решение.

      Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

      Самое читаемое