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 中对此进行了测试,并且都表现出相同的行为。这让我相信这不是代码中的某些东西或基于浏览器的特性,而是可能是某种服务器设置。
下面是项目的一些组合代码:
转储和设置 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 时,一切正常。
上一个和下一个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.page
或 session.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 作为页面的变量名称。 (这对我来说是违反直觉和令人反感的)我认为像分页这样的结构应该包含在一个文件或目录中,而不是整个站点。
感谢所有发表评论并帮助我完成这项工作的人。
有个问题很困扰我。我已经为 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 中对此进行了测试,并且都表现出相同的行为。这让我相信这不是代码中的某些东西或基于浏览器的特性,而是可能是某种服务器设置。
下面是项目的一些组合代码:
转储和设置 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 时,一切正常。
上一个和下一个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.page
或 session.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 作为页面的变量名称。 (这对我来说是违反直觉和令人反感的)我认为像分页这样的结构应该包含在一个文件或目录中,而不是整个站点。
感谢所有发表评论并帮助我完成这项工作的人。