这个过程相当简单:
控制器/动作方法
- 使用你的路由表,将你的 robots.txt 路径映射到控制器中的一个动作(我使用控制器和动作作为一个简单的例子来帮助你开始),就像你对给定路径的任何其他控制器和视图一样。
- 在操作中,检查请求中的域并为该域选择您的 robots.txt 内容。
- 使用以下内容从磁盘返回适当的文件:
以下示例假设有一个顶级 robots.txt 文件:
// In App_Start/RouteConfig:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "robots",
url: "robots.txt",
defaults: new { controller = "Seo", action = "Robots" }
);
// The controller:
public class SeoController : Controller {
public ActionResult Robots() {
var robotsFile = "~/robots-default.txt";
switch (Request.Url.Host.ToLower()) {
case "stackoverflow.com":
robotsFile = "~/robots-so.txt";
break;
case "meta.stackoverflow.com":
robotsFile = "~/robots-meta.txt";
break;
}
return File(robotsFile, "text/plain");
}
}
使其工作的最简单方法之一是确保runAllManagedModulesForAllRequests
在 web.config 中使用的所有请求都调用路由模块(不要使用它,请参阅下一段):
<system.webServer>
<handlers>
...
</handlers>
<modules runAllManagedModulesForAllRequests="true" />
</system.webServer>
这通常不是一件好事,因为现在所有静态文件(css、js、txt)在被转移到静态文件处理程序之前都经过托管处理程序。IIS非常擅长快速提供静态文件(一个主要是静态文件的网站会在 CPU 之前最大限度地使用您的磁盘 I/O),因此为了避免这种性能损失,推荐的方法是下面的 web.config 示例部分。ExtensionlessUrlHandler-Integrated-4.0
请注意与 Visual Studio MVC 4 模板应用程序中的处理程序的相似之处:
<system.webServer>
<handlers>
<add name="Robots-Integrated-4.0"
path="/robots.txt" verb="GET"
type="System.Web.Handlers.TransferRequestHandler"
preCondition="integratedMode,runtimeVersionv4.0" />
... the original handlers ...
</handlers>
<modules runAllManagedModulesForAllRequests="false" />
</system.webServer>
优点/缺点
一旦你开始使用这种方法,它的优点就会变得很明显:
- 您可以使用帮助程序动态生成 robots.txt 文件以生成操作 url,然后您可以将其全部/部分添加到模板 robots.txt 文件中。
- 您可以检查机器人用户代理以针对每个机器人用户代理返回不同的机器人文件
- 您可以使用相同的控制器为网络爬虫输出 sitemap.xml 文件
- 您可以从站点用户可以轻松管理的数据库表中管理机器人内容。
不利的一面是,
- 您的机器人文件现在使您的路线表复杂化,实际上并不需要
- 您将需要优化缓存以防止持续的磁盘读取。但是,这对于您采用的任何方法都是一样的。
还要记住,不同的 robots.txt 文件可用于不同的子目录。这对于路由和控制器方法变得很棘手,因此IHttpHandler
这种情况下的方法(如下)更容易。
IHttpHandler 方法
您也可以使用IHttpHandler
在 web.config 中注册的自定义来执行此操作。我强调自定义,因为这避免了让所有控制器看到所有请求的需要(使用runAllManagedModulesForAllRequests="true"
,与将自定义路由处理程序添加到路由表中不同。
这也可能是一种比控制器更轻量级的方法,但是您必须拥有巨大的站点流量才能注意到差异。它的另一个好处是一段可重用的代码,您可以将其用于所有站点。您还可以添加自定义配置部分来配置机器人用户代理/域名/路径映射到机器人文件。
<system.webServer>
<handlers>
<add name="Robots" verb="*" path="/robots.txt"
type="MyProject.RobotsHandler, MyAssembly"
preCondition="managedHandler"/>
</handlers>
<modules runAllManagedModulesForAllRequests="false" />
</system.webServer>
public class RobotsHandler: IHttpHandler
{
public bool IsReusable { get { return false; } }
public void ProcessRequest(HttpContext context) {
string domain = context.Request.Url.Host;
// set the response code, content type and appropriate robots file here
// also think about handling caching, sending error codes etc.
context.Response.StatusCode = 200;
context.Response.ContentType = "text/plain";
// return the robots content
context.Response.Write("my robots content");
}
}
子目录中的 robots.txt
要为子目录和站点根目录服务机器人,您不能轻易使用控制器方法;在这种情况下,处理程序方法更简单。这可以配置为将 robots.txt 文件请求提取到任何子目录并相应地处理它们。然后,您可以选择为某些目录返回 404,或者为其他目录返回 robots 文件的一个小节。
我在这里特别提到这一点,因为这种方法也可用于 sitemap.xml 文件,为站点的不同部分提供不同的站点地图,相互引用的多个站点地图等。
其他参考: