3

我们有一个服务器设置如下:

  • 视窗 2012 R2
  • Coldfusion 10,企业
  • IIS,配置自定义 404 页面(在服务器上执行)

自定义 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文件的)?

由 Thomas Gorgolione 启发,由我自己整理的解决方案

正如怀疑的那样,问题总是归结为被转发到 ISAPI_REDIRECT 模块的请求,即使相关文件不存在也是如此。

正如 Thomas 所建议的,一个优雅的解决方案是在将文件/目录传递给 ISAPI_REDIRECT 模块之前,利用重写来检查文件/目录是否确实存在。

虽然 Thomas 建议的软件可以解决问题,但我无法将其安装在 64 位 Windows 2012 R2 机器上。但是,我设法回退到使用 IIS8(可能还有早期版本)中包含的 URL 重写模块。

请参阅下面提供解决方案的我的 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 以该目录开头,它将作为正常请求传递。

谢谢大家的意见。

4

3 回答 3

3

注意:上面的问题也包括一个解决方案。

我认为这是 Coldfusion 连接器的错误。我会向 Adob​​e ( https://bugbase.adobe.com/ ) 发布错误报告。我确实有一个解决方法。我有同样的问题,但我使用 IIRF(Ionic IIS Redirector - http://iirf.codeplex.com/),我找到了一种方法来使用它来避免现在的错误:

  1. 删除 IIS/Coldfusion 中任何以前的 404 文件配置
  2. 按照它的安装说明正常安装 IIRF。
  3. 在 IirfGlobal.ini 文件(通常位于 C:\Windows\System32\inetsrv\IIRF)中,添加以下行:

    RewriteFilterPriority HIGH
    

    这将允许 IIRF 在到达 ColdFusion/Tomcat 之前处理 404 请求。

  4. 在特定于站点的 Iirf.ini 中(通常您在 Web 文件的根文件夹中创建一个 - 有关详细信息,请参阅 IIRF 文档),添加以下规则:

    RewriteCond %{SCRIPT_TRANSLATED} !-f
    RewriteCond %{SCRIPT_TRANSLATED} !-d
    RewriteRule ^(.+)$ page_to_redirect_to.cfm?404;$1 [L]
    

    这会将所有不存在的文件/目录重定向到 page_to_redirect_to.cfm,并像往常一样添加 404 查询字符串。

  5. 编辑:添加了以下步骤:进入 IIS 管理器并选择配置为使用 IIRF 的服务器或网站,然后进入 ISAPI 过滤器部分。单击“查看有序列表”,然后将 IIRF 过滤器移至顶部。

编辑 2:刚刚向 Adob​​e 发布了一个错误。请参阅https://bugbase.adobe.com/index.cfm?event=bug&id=3630245

希望有帮助。

于 2013-09-10T17:35:36.003 回答
2

让我先声明我仍在运行 ColdFusion 9,因此我没有第一手经验来使用 Tomcat 在 ColdFusion 10 中处理 404。显然我需要升级到版本 10,所以我试图让自己熟悉它的细微差别(比如处理 404)。所以我做了一些搜索。

正如您在问题中所述,对于 ColdFusion 9 和 IIS,最初请求的文件通常包含以CGI.QUERY_STRING“404;”开头的变量。对于 ColdFusion 10 和 Tomcat,它看起来好像一些其他CGI变量包含最初请求的文件,这取决于您的设置是哪个变量。

我发现了 Raymond Camden 的这篇博文 -提醒 - CGI-scope-there-is-more-to-the-CGI-scope-than-what-the-dump-shows。虽然这本身包含了很好的信息,但我还在Jules Gravinese的评论中发现了以下内容:

使用IIS7时,变量为CGI.HTTP_X_ORIGINAL_URL

使用ISAPI_rewrite时,变量为CGI.HTTP_X_REWRITE_URL

使用APACHE时,变量为CGI.REDIRECT_URL

我还发现其他一些文章引用了一个变量,我相信在使用APACHECGI.REDIRECT_QUERY_STRING时也包含该变量。


从 Adob​​e 找到另一篇关于 CGI 变量以及它们如何与 ColdFusion 一起使用的文章(以及如何/为什么它不是完整列表):CGI 环境(CGI Scope)变量


注意: 我还发现了这个错误ColdFusion 10.0 - 错误 3488063:作为 .cfm 文件的 IIS 404 自定义错误处理程序 URL 不会始终返回已关闭的整个文档,但最近的一些评论表明它仍然是一个问题。所以请注意这一点。

于 2013-09-09T14:02:04.753 回答
1

使用Application.cfc OnMissingTemplate 方法来处理丢失的模板页面。

在 Application.cfc 添加这个

<cffunction name="onMissingTemplate">
    <cfargument name="targetPage" type="string" required=true/>

    <!--- No standard error handling here so we need to try/catch --->
    <cftry>
        <!--- Can't do a redirect so we'll do an "include" --->
        <cfset missingPage=Arguments.targetPage>
        <cfinclude template="/errors/404.cfm">

        <cfcatch>
          <!--- Let the standard missing file (404) process occur --->
            <cfreturn false />
        </cfcatch>
    </cftry>
</cffunction>

在 /errors/404.cfm 在顶部附近添加

<cfparam name="missingPage" type="string" default="">
<cfif missingPage eq "">
  <!--- Include CGI variable and process as fitting for your purposes --->
  <cfset missingPage=CGI.QUERY_STRING>
</cfif>
于 2013-09-09T13:51:55.783 回答