我们的服务器设置如下:
自定义404页(CFM文件)处理缺失的URL,并对照数据库中的自定义URL检查它们。如果找到匹配项,它将显示相关数据。当自定义URL映射到不存在的CFM文件时,就会发生此问题。例如。
/home/map.cfm(不是真实文件或目录)
现在,当用户请求此URL时,服务器将看到它是CFM文件,并将其正确地传递给ColdFusion(通过ISAPI重定向)。Tomcat看到此文件实际上不存在,并返回404。IIS看到此404消息并执行自定义错误页面(/errors/404.cfm)。
产生的CGI变量实际上并不使我们能够检索原始URL(以将其映射到数据库中的虚拟URL),通常将其作为CGI.QUERY_STRING变量的一部分提供。相反,QUERY_STRING变量在“ jakarta”目录中包含“ isapi_rewrite.dll”文件的路径。
在Tomcat返回所述页面的404错误之后,有什么方法可以保留原始请求的URL(CFM文件的URL)?
解决方案,由我自己设计,灵感来自Thomas Gorgolione
可以怀疑,问题始终归结为将请求转发到ISAPI_REDIRECT模块,即使该文件不存在。
正如Thomas所建议的那样,一种优雅的解决方案是在将其传递给ISAPI_REDIRECT模块之前,利用重写检查文件/目录是否确实存在。
尽管Thomas提出了可以解决问题的软件,但我无法将其安装在64位Windows 2012 R2计算机上。但是,我设法回过头来利用IIS8(可能还有更早版本)附带的URL Rewrite模块。
请参阅下面提供解决方案的web.config条目。
<?xml version="1.0" encoding="UTF-8"?> <configuration> <system.webServer> <httpErrors> <remove statusCode="404" subStatusCode="-1" /> </httpErrors> <rewrite> <rules> <rule name="404 HTTP"> <match url="(.*)" /> <conditions> <add input="{REQUEST_URI}" pattern="CFFileServlet/(.*)" negate="true" /> <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" /> <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" /> <add input="{SERVER_PORT_SECURE}" pattern="0" /> </conditions> <action type="Rewrite" url="/404.cfm?404;http://{HTTP_HOST}:{SERVER_PORT}{REQUEST_URI}" /> </rule> <rule name="404 HTTPS"> <match url="(.*)" /> <conditions> <add input="{REQUEST_URI}" pattern="CFFileServlet/(.*)" negate="true" /> <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" /> <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" /> <add input="{SERVER_PORT_SECURE}" pattern="1" /> </conditions> <action type="Rewrite" url="/404.cfm?404;https://{HTTP_HOST}:{SERVER_PORT}{REQUEST_URI}" /> </rule> </rules> </rewrite> </system.webServer> </configuration>
上面的配置文件同时考虑了HTTP和HTTPS请求。它还将考虑CFFileServlet目录,ColdFusion使用该目录托管临时图像和资产。如果URL以该目录开头,它将作为常规请求传递。
感谢大家的投入。
注意:上面的问题也包括一个解决方案。
我认为这是Coldfusion连接器的错误。我会将错误报告发布到Adobe(https://bugbase.adobe.com/)。我确实有解决方法。我有同样的问题,但是我使用IIRF(离子IIS重定向器- http: //iirf.codeplex.com/),并且我找到了一种使用该方法避免该错误的方法:
RewriteFilterPriority HIGH
这样一来,IIRF甚至可以在击中ColdFusion / Tomcat之前处理404请求。
RewriteCond %{SCRIPT_TRANSLATED} !-f
RewriteCond %{SCRIPT_TRANSLATED} !-d RewriteRule ^(.+)$ page_to_redirect_to.cfm?404;$1 [L]
这会将所有不存在的文件/目录重定向到page_to_redirect_to.cfm,并像平常一样添加404查询字符串。
编辑2: 刚刚向Adobe发布了一个错误。参见https://bugbase.adobe.com/index.cfm?event=bug&id=3630245
希望能有所帮助。