Coldfusion URL 变量意外更改

Coldfusion URL variable changes unexpectedly

有个问题很困扰我。我已经为 Coldfusion 11 上 运行 的页面编写了一个基本的分页工具:http://fftoolbox.scout.com/ffwc/rankings.cfm?rankings=season&page=2

我将其设计为有一个名为 page 的 url 查询,其中包含页码。这样,用户只需键入他想要的页码,而不必按下一个和上一个按钮。

第 1 - 25 页的分页效果很好,但在第 26 页及之后,它将 url.page 变量记录为 1,即使控件上的 link 清楚地显示变量应为第 26 页。

如果您注意到,我在页面顶部有 coldfusion 转储 URL 范围。您会注意到,当页面等于或小于 25 时,页面会正确报告。但是,任何超过 25 的值,url.page 都会被分配一个值 1,即使这不是根据浏览器发送的值。我已经在 FF、Chrome 和 IE 中对此进行了测试,并且都表现出相同的行为。这让我相信这不是代码中的某些东西或基于浏览器的特性,而是可能是某种服务器设置。

下面是项目的一些组合代码:

  1. 转储和设置 session 变量。

    <cfdump var='#url#'>
    <cfif not StructKeyExists(url,'page')>
        <cfset session.page = 1>
    <cfelse>
        <cfset session.page = url.page>
    </cfif>
    
    <cfset startingRank =  (session.page - 1)*50 +1>
    <cfset endingRank = (session.page - 1)*50 +50>
    

此起始和结束排名用于 SQL 查询以检索适当的玩家范围。我不包括 SQL 除非有人要求它工作正常。事实上,当我将 url.page 硬编码为 26 时,一切正常。

  1. 上一个和下一个links:

    <tr><td colspan='2' style='text-align: center'>
    <cfif session.page gt 1>
        <a href='./rankings.cfm?rankings=season&action=#Evaluate(session.page - 1)#'>Previous</a>
    </cfif></td>
    <td colspan='2' style='text-align: center'>
    <cfif session.page lt Evaluate(Int((GetMax.recordCount -1)/50) +1)>
         <a href='./rankings.cfm?rankings=season&page=#Evaluate(session.page + 1)#'>Next</a>
    </cfif></td></tr>
    

如果您需要更多信息,请告诉我。我认为这实际上是 Apache 问题或 CF 问题,因为分页在第 1 页到第 25 页上正常工作。

编辑:

我收到了显示查询的请求。有两个。一个获取数据,另一个获取整组数据的计数。

<cfquery name='GetData' datasource='XXXXXXXX'>
    select * from
        (select @currentRank := @currentRank +1 as rank,player_name, point_sum, contest_type from
           (select player_name,sum(points) as point_sum, contest_type, (select @currentRank := 0) r
             from 2014_ranking_season
             inner join ecom_item_type on ecom_item_type.ecom_item_type_id = 2014_ranking_season.contest_type
             where contest_type = #session.filter#
             group by player_name)t1
        order by point_sum desc)t2
    where rank between #startingRank# and #endingRank#
</cfquery>

<cfquery name='GetMax' datasource='XXXXXXXX'>
    select * from
        (select @currentRank := @currentRank +1 as rank,player_name, point_sum, contest_type from
           (select player_name,sum(points) as point_sum, contest_type, (select @currentRank := 0) r
             from 2014_ranking_season
             inner join ecom_item_type on ecom_item_type.ecom_item_type_id = 2014_ranking_season.contest_type
             where contest_type = #session.filter#
             group by player_name)t1
        order by point_sum desc)t2
</cfquery>

希望对您有所帮助。请记住,除了我正在试验的前一个按钮外,在页面 > 25 之前一切正常。

编辑:

GetMax.recordCount 的值 = 2242。此外,我正在编写一个小的复制页面,该页面按比例缩小以仅生成结果。一旦完成,我将 post 整个页面的代码。无论它是否重现结果,它都会告诉我们一些事情。

编辑:

重现页面已到位,错误可重现,即使使用缩小的代码也是如此。这是 URL:http://fftoolbox.scout.com/ffwc/testPagination.cfm?rankings=season&page=26

这是完整的代码清单:

<cfdump var='#url#'>

<cfset session.page = 1>

<cfif StructKeyExists(url,'page')>
        <cfset session.page = url.page>
</cfif>

<cfset startingRank =  (session.page - 1)*50 +1>
<cfset endingRank = (session.page - 1)*50 +50>

<cfif not StructKeyExists(session,'filter')>
        <cfset session.filter = 0>
</cfif>

<cfparam name="url.rankings" default="season">

<html>
    <head>
            <title>Test Pagination</title>
    </head>
    <body>

                    <br /><br />
<cfoutput>

    <table width='99%' cellpadding='5' cellspacing='0'><tr class='header'>
    <cfset count = 0>
            <cfquery name='GetData' datasource='fftoolbox_sql'>
                    select * from
                            (select @currentRank := @currentRank +1 as rank,player_name, point_sum, contest_type from
                                    (select player_name,sum(points) as point_sum, contest_type, (select @currentRank := 0) r
                                    from 2014_ranking_season
                                    inner join ecom_item_type on ecom_item_type.ecom_item_type_id = 2014_ranking_season.contest_type
                                    group by player_name)t1
                            order by point_sum desc)t2
                    where rank between #startingRank# and #endingRank#
            </cfquery>
            <cfquery name='GetMax' datasource='fftoolbox_sql'>
                    select * from
                            (select @currentRank := @currentRank +1 as rank,player_name, point_sum, contest_type from
                                    (select player_name,sum(points) as point_sum, contest_type, (select @currentRank := 0) r
                                    from 2014_ranking_season
                                    inner join ecom_item_type on ecom_item_type.ecom_item_type_id = 2014_ranking_season.contest_type
                                    group by player_name)t1
                            order by point_sum desc)t2
            </cfquery>
            <th>RANK</th><th>PLAYER NAME</th><th>TEAM NAME</th><th>POINTS</th></tr>
            <cfloop query='GetData'>
                    <cfquery name='GetOneName' datasource='fftoolbox_sql'>
                            select team_name
                            from 2014_ranking_season
                            where player_name = <cfqueryparam cfsqltype='CF_SQL_VARCHAR' value='#GetData.player_name#'>
                            limit 1
                    </cfquery>
                    <cfset name = URLEncodedFormat(#player_name#)>
                    <tr <cfif #count#%2 eq 0>class='evenRow'<cfelse>class='oddRow'</cfif>><td>#rank#</td>
                            <td><a href='./player.cfm?name=#variables.name#' target='_blank'>#player_name#</a></td><td>#GetOneName.team_name#</td><td>#point_sum#</td></tr>
                            <cfset count++>
            </cfloop>
            <tr><td colspan='2' style='text-align: center'>
            <cfif session.page gt 1>
                    <a href='./testPagination.cfm?rankings=season&page=#Evaluate(session.page - 1)#'>Previous</a>
                                                                    </cfif></td>
            <td colspan='2' style='text-align: center'>
            <cfif session.page lt Evaluate(Int((GetMax.recordCount -1)/50) +1)>
                    <a href='./testPagination.cfm?rankings=season&page=#Evaluate(session.page + 1)#'>Next</a>
            </cfif></td></tr>

    </table>
</cfoutput>
        </body>
</html>

我还将获得要在该页面上显示的 http 请求 headers。如果人们愿意,我会把它们放在问题中,但问题开始变得很长,并且 cfdump 在浏览器中很好地格式化了它。谢谢大家一直以来的互动。

更新:

我怀疑我们的配置团队(我无法控制)可能在后端做了一些事情,比如把它放在清漆上,这是不应该发生的。请继续查看代码等,我会树上这棵树,看看他们是否做了什么。 25 似乎只是 "human" 一个数字,因为它不是某处的设置。我会让你 posted。

更新:

我已经与供应团队核实过,清漆未激活,负载平衡也没有导致问题,因为我可以在绕过 LB 时重现该问题。我认为这是 Apache 或 CF 的配置问题似乎越来越有可能,因为我们排除了一切。

更新:

加上@Leigh推荐的代码,发现http请求肯定是page=26,URL scope肯定是page=1。我正在查看应用程序文件是否可能会弄乱它。

最终更新:

检查 Application.cfm 后,我发现了以下代码:

<cfif cgi.script_name NEQ "/ffwc/all-time-leaderboard.cfm">
    <cfset ValidPages = "1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25">
    <cfif IsDefined("url.page") and ListFind(ValidPages,url.page) eq 0>
            <cfset url.page = 1>
    </cfif>
</cfif>

注释掉后,分页效果很好。使其工作的另一种替代方法是不使用 page 作为页面的变量名称。 (这对我来说是违反直觉和反感的)我认为像分页这样的结构应该包含在一个文件或目录中,而不是整个站点。

首先,您的 "previous" 按钮没有设置 URL.pagesession.page - 它使用 "action." 因为 page 没有定义在 URL 中,它会自动将页面设置为一个...因此无论我从哪里开始,点击 "previous" 然后 "next" 总是让我回到第 2 页。

现在,你的 "next" link...

 <cfif session.page lt Evaluate(Int((GetMax.recordCount -1)/50) +1)>
    <a href='./rankings.cfm?rankings=season&page=#Evaluate(session.page + 1)#'>Next</a>
 </cfif>

在我自己的 .cfm 页面上设置 session.page 后,我只是 运行 这段代码...

只有当 session.page 为零或 GetMax.recordcount 大于 session.page 的值的 50 倍时,"Next" 按钮才会显示。我对此提出异议,因为 GetMax.recordcount 不应该改变。您一次显示 50 条记录。

以下代码不起作用,所以我不知道你在做什么...

<cfset GetMax.recordcount = 50>
<cfset session.page = 1>

<cfoutput>
<cfif session.page lt Evaluate(Int((GetMax.recordCount -1)/50) +1)>
     <a href='./rankings.cfm?rankings=season&page=#Evaluate(session.page + 1)#'>Next</a>
</cfif>
</cfoutput>

可能是时候向我们展示查询逻辑了。

编辑:

为什么不做这样的事情呢?

<cfset StartRecord = #url.page# * 50 - 49>

<cfquery name="listOfPeople" datasource="XXX">
SELECT TOP 50 *
FROM PeopleTable
WHERE PeopleID >= #StartRecord#
</cfquery>

它是如此简单,我只是不明白为什么需要查询 GetMax。所有涉及的额外数学运算只会增加出错的风险。分页本身不应该是一个项目。

检查 Application.cfm 后,我发现了以下代码:

<cfif cgi.script_name NEQ "/ffwc/all-time-leaderboard.cfm">
    <cfset ValidPages = "1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25">
    <cfif IsDefined("url.page") and ListFind(ValidPages,url.page) eq 0>
            <cfset url.page = 1>
    </cfif>
</cfif>

注释掉后,分页效果很好。使其工作的另一种替代方法是不使用 page 作为页面的变量名称。 (这对我来说是违反直觉和令人反感的)我认为像分页这样的结构应该包含在一个文件或目录中,而不是整个站点。

感谢所有发表评论并帮助我完成这项工作的人。