游客发表
服务器返回500错误,误页浏览器却显示404页面——这事儿我干过。面跳当时客户要求所有错误都统一跳到一个“友好提示页”,误页但那个页面必须返回404状态码,面跳否则搜索引擎会把错误页当成正常内容收录。误页问题来了:ASP的面跳默认错误处理直接吐500,你就算在页面上写满“404 Not Found”,误页HTTP头还是面跳500。搜索引擎不傻。误页
要解决这个,面跳得从两个层面动手:一是误页让ASP捕获错误,二是面跳强制修改HTTP状态码。IIS自带的误页500-100错误页重定向只是表面功夫,状态码没变,面跳等于白干。误页
ASP里有个Server.GetLastError(),能拿到当前错误的详细信息。但默认情况下,一旦脚本出错,IIS会直接返回500.100,根本不给你插手的机会。你得在IIS管理器里把“自定义错误”中的500-100指向一个自定义ASP文件,比如/error/404.asp。这一步是入口。
但光这样不够。那个404.asp文件里,第一行必须写:
<% Response.Status = "404 Not Found" %> 注意,这行代码要放在所有HTML输出之前。一旦有空格或者换行输出到浏览器,状态码就改不了了。我踩过这个坑——文件开头有个空行,结果状态码死活改不动,查了半小时才发现是BOM头搞的鬼。
有人喜欢用Response.Redirect("/404.asp")。这会导致302跳转,最终页面返回200。搜索引擎看到的是“这个URL先302到另一个URL,然后那个URL返回200”,完全不是404。正确做法是用Server.Transfer("/404.asp"),服务器内部转发,URL不变,状态码可以自己控制。
但Server.Transfer有个限制:它只能在同一个应用程序池内跳转。如果你把404.asp放在另一个站点,那就没戏。我一般直接把404.asp放在根目录,所有错误都往那儿转。
假设你有一个default.asp,里面有个数据库查询,表不存在,ASP抛错。IIS会调用你配置的500-100错误页,也就是/error/404.asp。这个文件的内容:
<% Response.Status = "404 Not Found" Response.Write "<h1>页面不存在</h1>" Response.Write "<p>您访问的资源已被移除或从未存在。</p>" %> 就这么简单。但注意:如果错误发生在404.asp自己身上,比如它也有语法错误,那IIS会陷入死循环,最后返回一个空白页。所以这个文件必须写得极其简单,不要连数据库,不要包含其他文件。
IIS 6和IIS 7+的处理方式不一样。IIS 6里,你需要在“应用程序配置”的“错误页”里设置500-100的URL为/error/404.asp。IIS 7以上,要在“错误页”功能里添加一个500的状态码,然后指定“执行URL”为/error/404.asp,并且勾选“尝试从本地请求中返回详细错误”。不勾这个,IIS会直接返回一个通用错误页,你的ASP根本不执行。
我见过有人用web.config的<httpErrors>节点,但那个是IIS级别的,跟ASP的Server.GetLastError()不互通。你要么全用IIS错误页,要么全用ASP自定义错误。混着用,状态码会乱。
写一个test.asp,内容就一行:<% x = 1/0 %>。访问它,看返回的HTTP状态码是不是404。用浏览器开发者工具的网络面板看,或者用curl -I。如果返回500,说明你的配置没生效。检查IIS错误页设置,检查404.asp文件开头有没有多余字符,检查是否用了Server.Transfer而不是Response.Redirect。
最后说个真事:有次我帮人调这个,折腾半天发现是杀毒软件在拦截Server.Transfer,把它当成了可疑的内部跳转。关了杀毒软件立马正常。所以,如果代码没问题,配置也没问题,想想是不是安全软件在捣乱。
友情链接