【问题标题】:ColdFusion with IIS URL Rewrite - Page never finishes loading带有 IIS URL 重写的 ColdFusion - 页面永远不会完成加载
【发布时间】:2013-09-16 22:39:40
【问题描述】:

我在安装了 URL 重写模块的 IIS 7.5 上运行 CF10。 所有重写规则都运行良好,ColdFusion 正在返回正确的页面。为了让页面显示在浏览器中,我必须像这样在 Application.cfc 中手动设置“内容长度”值:

<cfcomponent>

  <cffunction name="onRequestEnd">

  <cfheader name="Content-Length" value="#getPageContext().getCFOutput().getBuffer().size()#" />

  </cffunction>

</cfcomponent>

如果没有此代码,浏览器将不会显示该页面。但是,即使它现在正在显示页面,但它并没有正确执行。页面从未完全加载完毕,而且页面上似乎并非所有 HTML 内容。

我尝试在设置“内容长度”后添加一个&lt;cfflush /&gt; 标记,但没有区别。我不明白为什么会发生这种情况,但我知道使用 htaccess 的其他人发生了这种情况:http://forums.devshed.com/coldfusion-development-84/page-not-finishing -loading-coldfusion-and-htaccess-bug-575906.html

编辑:出站/入站规则定义示例:

<!--- Outbound rule --->
<rule name="Rewrite Info Page" preCondition="IsHTML" enabled="false" stopProcessing="false">
<match filterByTags="A" pattern="^(.*)/info\.cfm\?subjectid=([^=&amp;]+)&amp;(?:amp;)?nameid=([^=&amp;]+)$" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
</conditions>
<action type="Rewrite" value="{R:1}/info/{R:2}/{R:3}" />
</rule>

<preConditions>
<preCondition name="IsHTML">
<add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
</preCondition>


<!--- Inbound rule --->
<rule name="Rewrite Info Page" enabled="true" stopProcessing="false">
<match url="^(.*)/info/([^/]+)/([^/]+)/?$" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="{R:1}/info.cfm?subjectid={R:2}&amp;nameid={R:3}" appendQueryString="true" />
</rule>

出站规则是查看&lt;a&gt; 标记内的 URL 链接,看起来像 http://mysite.com/info.cfm?subjectid=1&amp;nameid=1,然后将其重写为在我的页面上显示为 http://mysite.com/info/1/1

Inbound 正在寻找一个看起来像 http://mysite/info/1/1 的链接并将其解析/重写为真实的 URL,即 http://mysite.com/info.cfm?subjectid=1&amp;nameid=1

【问题讨论】:

  • 我怀疑它是重写模块,但为了排除故障,将其关闭并通过不受干扰的 URL 访问页面。相同的?任何页面都一样吗?查看一些 CF 监控并检查 CF 是否认为它已经完成了对请求的处理,或者它是否没有释放它。重新安装 Web 服务器连接器,看看是否有帮助。
  • 嗨亚当,我已经这样做了,当重写模块关闭时没有问题。因此它与 IIS 重写模块有关。我现在正在尝试使用 apache mod_rewrite 的 helicon ape,看看我是否可以让它工作
  • 原来 mod_rewrite 不能即时更改 HTML 内容 :( 这意味着我的所有 URL 都必须在我的 CF 代码中重写为友好 URL。这在检查时会让人头疼用于孤立/损坏的链接。
  • 打开浏览器开发工具(Firebug 或类似工具)并在页面加载时观察网络流量。您的任何链接资产是否返回任何 404 或其他 HTTP 错误代码?将文件从 /path/file.cfm 重写为 /path/file/ 会破坏代码中的相对路径引用,导致 CSS、图像和 JavaScript 根本无法工作。
  • 完全没有 404 错误。标题看起来也不错。但是浏览器会继续显示一个旋转的图标,等待页面加载。我注意到有时并非所有的 HTML 都会输出到浏览器,当 Outbound 打开时,Firebug 会以缓慢的响应时间返回。我很确定出站链接重写花费的时间太长(我的页面上有很多链接),这导致 ColdFusion 不正常地返回页面。这就是为什么我必须手动设置 content-length 标头,以便页面即使在加载问题的情况下也能显示在浏览器中。

标签: coldfusion iis-7.5 coldfusion-10 url-rewrite-module


【解决方案1】:

由于 IIS URL Rewrite 的出站规则给您带来了很多麻烦,这里有另一种选择。使用 ColdFusion 重写 onRequestEnd 中的链接。这将允许您在 IDE 中使用物理路径、使用默认文档,并且仍然可以将出站 URL 以所需格式发送到浏览器。我有updated my Gist with the details

这是一个非常基本的方法。关闭 web.config 中的出站重写规则,并将类似这样的内容添加到 Application.cfc 中的 onRequestEnd 函数中。 (我的正则表达式很糟糕,所以这个reReplace() 模式只能部分地像你的 IIS 模式那样工作。

<cfcomponent>

    <cffunction name="onRequestEnd">
        <!--- Get the generated output --->
        <cfset var output = getPageContext().getCFOutput().getBuffer().toString()>      

        <!--- Apply outbound link rules --->
        <cfset output = reReplace(output, '/info\.cfm\?subjectid=([^=&amp;]+)', '/info/\1', 'all')>

        <!--- Clear the previous output and send the rewritten output in its place --->
        <cfcontent reset="true">
        <cfoutput>#output#</cfoutput>

    </cffunction>

</cfcomponent>

它的性能不如 IIS 中的 URL 重写模块,但它会为您提供您想要实现的所有其他功能(一旦您调整了正则表达式)。

【讨论】:

  • 这很有趣。我在考虑这些方面的一些事情,也许不像你描述的那么优雅。你认为这样做会比使用 IIS 重写模块使用更多的服务器资源(我猜主要是 CPU)吗?
  • @volumeone,就像我说的,它的性能不如 URL Rewrite 模块。与 ColdFusion 相比,URL Rewrite 更“接近金属”。 ColdFusion 是一种高级语言,必须编译成 Java,它在 JVM 之上运行,然后与操作系统交互。此外,Java 以在字符串操作方面比其他语言慢而闻名。以这种方式实施出站重写规则应谨慎进行,并进行彻底的负载测试,以确保不会产生任何不利影响。
【解决方案2】:

我能够让您的出站规则像在我的本地开发环境中一样工作(尽管运行的是 CF9)。唯一的麻烦是将出站规则包装在正确的 XML 元素中。

之后,IIS 告诉我不能将出站规则应用于 gzip 压缩的内容,所以我不得不在配置中添加 &lt;urlCompression doStaticCompression="true" doDynamicCompression="false"/&gt;

有了这些,出站重写工作完美。我什至在一个有超过 20,000 个链接的页面上运行它,它处理得很好。

这是我的&lt;rewrite&gt; web.config 部分以及&lt;urlCompression&gt; 位:

    <rewrite>
        <rules>
            <rule name="Rewrite Info" enabled="true" stopProcessing="false">
                <match url="^(.*)/info/([^/]+)/([^/]+)/?$" />
                <conditions logicalGrouping="MatchAll" trackAllCaptures="false">
                    <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
                    <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
                </conditions>
                <action type="Rewrite" url="{R:1}/info.cfm?subjectid={R:2}&amp;nameid={R:3}" appendQueryString="true" />
            </rule>
        </rules>
        <outboundRules>
            <rule name="Rewrite Info Page" preCondition="IsHTML" enabled="true" stopProcessing="false">
                <match filterByTags="A" pattern="^(.*)/info\.cfm\?subjectid=([^=&amp;]+)&amp;(?:amp;)?nameid=([^=&amp;]+)$" />
                <conditions logicalGrouping="MatchAll" trackAllCaptures="false">
                </conditions>
                <action type="Rewrite" value="{R:1}/info/{R:2}/{R:3}" />
            </rule>
            <preConditions>
                <preCondition name="IsHTML">
                    <add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
                </preCondition>
            </preConditions>
        </outboundRules>
    </rewrite>
    <urlCompression doStaticCompression="true" doDynamicCompression="false"/>

我发现在onRequestEnd 中包含&lt;cfheader name="Content-Length" value="#getPageContext().getCFOutput().getBuffer().size()#" /&gt; 时结果没有差异。

但是,由于您获得了微调器并且页面似乎从未完全加载,您可以尝试显式刷新并关闭 onRequestEnd 中的响应,以确保完成向 IIS 的切换:

<cfscript>
    var response = getPageContext().getResponse().getResponse();
    var out = response.getOutputStream();
    out.flush();
    out.close();
</cfscript>

【讨论】:

  • 由于示例规则中的一些错误,我再次编辑了我的问题。 “课程”这个词不应该有任何东西。我很惊讶它对你有用....我已经尝试过两台单独的开发机器,甚至是生产机器,但一直遇到同样的问题。我现在会检查你的代码......
  • @volumeone,这解释了为什么入站规则不起作用。 :o) 我在答案中修改了 web.config 代码以反映更改。入站规则现在对我有用。
  • 刚试了一下,对我不起作用。一定和CF10新的Tomcat服务器有关?
  • 基于应用服务器到 Web 服务器的架构,ColdFusion 已经将控制权交还给 IIS。所以CF10 不应该有所作为。我怀疑还有其他一些环境问题在起作用。也许您的 web.config 中的其他设置。我建议再做两件事:1)在出站规则中将 stopProcessing="false" 更改为 stopProcessing="true"。可能有正在处理的其他规则会产生干扰。 2) 将您的 CFM 页面和 web.config 文件剥离到最基本的部分,看看它是否有效。然后一次一个地添加,找出罪魁祸首。
  • 您是对的,出站规则确实有效。但是,一旦出站规则重写了链接,请尝试单击一个链接以将您带到另一个具有更多链接的页面。除非我手动将其放入 content-length 标头中,否则它会中断...然后页面永远不会完成加载。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-05-16
  • 2013-09-19
  • 1970-01-01
  • 1970-01-01
  • 2017-05-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多