这个过程相当简单:
控制器/动作方法的方法
- 使用路由表,将您的robots.txt路径映射到控制器中的一个动作(我使用控制器和动作作为简单示例来帮助您入门),就像您为给定路径映射任何其他控制器和视图一样。
- 在动作中,检查请求中的域并为该域选择您的robots.txt内容。
- 使用类似以下方式从磁盘返回适当的文件:
以下示例假定存在一个顶级 robots.txt 文件:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "robots",
url: "robots.txt",
defaults: new { controller = "Seo", action = "Robots" }
);
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");
}
}
最简单的方法是确保在web.config中使用runAllManagedModulesForAllRequests
来调用路由模块,以便为所有请求调用路由模块(不建议使用这种方法,请参见下一段):
<system.webServer>
<handlers>
...
</handlers>
<modules runAllManagedModulesForAllRequests="true" />
</system.webServer>
一般来说,这不是件好事情,因为现在所有静态文件(css、js、txt)都会通过受控处理程序进行处理,然后才能转到静态文件处理程序。IIS非常擅长快速提供静态文件(一个大部分为静态文件的网站将在CPU之前耗尽磁盘I/O),所以为了避免这种性能损失,推荐的方法如下方的web.config示例部分。请注意与Visual Studio MVC 4模板应用程序中的ExtensionlessUrlHandler-Integrated-4.0处理程序的相似之处:
<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>
优缺点
一旦你开始使用这种方法,它的优点就变得明显了:
- 您可以使用帮助程序生成Action url来动态生成robots.txt文件,然后将其全部或部分添加到模板robots.txt文件中。
- 您可以检查机器人用户代理以返回不同的机器人文件。
- 您可以使用相同的控制器输出网页爬虫的sitemap.xml文件。
- 您可以通过数据库表管理机器人内容,该表可以轻松地由站点用户管理。
缺点是:
- 您的robots文件现在复杂化了路由表,而实际上并不需要这样做。
- 您需要优化缓存以防止不断的磁盘读取。但是,无论采用哪种方法,都需要这样做。
还要记住,不同的子目录可以使用不同的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;
context.Response.StatusCode = 200;
context.Response.ContentType = "text/plain";
context.Response.Write("my robots content");
}
}
子目录中的robots.txt
为了为子目录和站点根目录提供机器人服务,您不能轻松使用控制器方法;在这种情况下,处理程序方法更简单。可以配置该方法以捕获任何子目录上的robots.txt文件请求,并相应地处理它们。然后,您可能会选择为某些目录返回404,或者为其他目录的子部分返回robots文件的子段。
我特别在此处提到这一点,因为该方法也可用于sitemap.xml文件,以为网站的不同部分提供不同的站点地图,多个互相引用的站点地图等。
其他参考: