好的,出于某种奇怪的原因,一旦在Application.cfm文件中设置了request.dsn和我创建的另一个名为request.cfcDIR的变量,它们就不会被保留。
这里是上述两个变量的值的来源。
<cfset chkURL = "#CGI.HTTP_HOST#">
<cfif ((chkURL) EQ "url.subdomain.here" OR (chkURL) EQ "url.subdomain.here.a" OR (chkURL) EQ "url.subdomain.here.b" OR (chkURL) EQ "url.subdomain.here.c")>
<cfset whichDB = "1,2,3,4,5,6">
<cfelse>
<cfset whichDB = "0">
</cfif>
<!--- Start Check for Which DB the user resides and overwrite the request.dsn variable in Application.cfm --->
<cfif ((whichDB) NEQ 0 OR (whichDB) NEQ "")>
<cfset whichDB = "#whichDB#">
<cfif (whichDB) EQ 0>
<cfset request.dsn = "xxxxx_1">
<cfelse>
<!--- Loop through the whichDB list --->
<cfloop list="#whichDB#" delimiters="," index="i">
<cfquery name="CheckDB" datasource="xxxxx_#i#">
Select username,db,compid
FROM users
WHERE username = <cfqueryparam value="#FORM.username#" cfsqltype="cf_sql_varchar" maxlength="20">
</cfquery>
<!--- Here we check for which database has the results which originates from the Query(CheckDB) above
***IMPORTANT*** in order for this to work properly your Coldfusion DSN must named xxxxx_1, xxxxx_2 and so on...--->
<cfif (CheckDB.RecordCount) NEQ 0 AND (CheckDB.db) EQ 1>
<cfset client.dsn = "xxxxx_1">
<cfset client.cfcDIR = "cfcV5">
<cfset request.dsn = "xxxxx_1">
<cfset request.cfcDIR = "cfcV5">
<cfbreak/>
<cfelseif (CheckDB.RecordCount) NEQ 0 AND (CheckDB.db) EQ 2>
<cfset client.dsn = "xxxxx_2">
<cfset client.cfcDIR = "cfc">
<cfset request.dsn = "xxxxx_2">
<cfset request.cfcDIR = "cfc">
<cfbreak/>
<cfelseif (CheckDB.RecordCount) NEQ 0 AND (CheckDB.db) EQ 3>
<cfset client.dsn = "xxxxx_3">
<cfset client.cfcDIR = "cfcV5">
<cfset request.dsn = "xxxxx_3">
<cfset request.cfcDIR = "cfcV5">
<cfbreak/>
<cfelseif (CheckDB.RecordCount) NEQ 0 AND (CheckDB.db) EQ 4>
<cfset client.dsn = "xxxxx_4">
<cfset client.cfcDIR = "cfc">
<cfset request.dsn = "xxxxx_4">
<cfset request.cfcDIR = "cfc">
<cfbreak/>
<cfelseif (CheckDB.RecordCount) NEQ 0 AND (CheckDB.db) EQ 5>
<cfset client.dsn = "xxxxx_5">
<cfset client.cfcDIR = "cfcV5">
<cfset request.dsn = "xxxxx_5">
<cfset request.cfcDIR = "cfcV5">
<cfbreak/>
<cfelseif (CheckDB.RecordCount) NEQ 0 AND (CheckDB.db) EQ 6>
<cfset client.dsn = "xxxxx_6">
<cfset client.cfcDIR = "cfcV5">
<cfset request.dsn = "xxxxx_6">
<cfset request.cfcDIR = "cfcV5">
<cfbreak/>
<cfelse>
<cfset request.dsn = "xxxxx_1">
</cfif>
</cfloop>
</cfif>
</cfif>因此,当Application.cfm获得设置的变量时,上面的代码可以很好地工作。然而,request.dsn并不可靠,就好像我从一开始就没有定义过它。为了安全起见,我在上面的代码中定义了两次变量。
下面是Application.cfm文件的样子。
<cfapplication name="Appname-here"
sessionmanagement="yes"
clientstorage="cookie"
clientmanagement="Yes"
loginstorage="session"
scriptprotect="all"
sessionTimeout = #CreateTimeSpan(0, 0, 10, 0)#>
<cfswitch expression="#CGI.HTTP_HOST#">
<cfcase value="url.subdomain.here">
<cfif IsDefined("request.dsn")>
<cfset request.dsn = '#client.dsn#'>
</cfif>
<cfset request.cfcDIR = #client.cfcDIR#>
</cfcase>
<cfdefaultcase>
<cfset request.dsn = 'xxxxx_1'>
<cfset request.cfcDIR = cfcV5>
<cfdefaultcase>
</cfswitch>因此,当用户转到要登录的定义用户页面时,我得到一个错误,指出"Element DSN is undefined in REQUEST“,这是胡扯,因为正在定义。(Coldfusion 10)
发布于 2016-04-29 02:13:00
“请求范围”存在于单个请求的生命周期内。除非你的<cfapplication ...>标签上面有什么东西,否则下面这行是这样写的:
<cfif IsDefined("request.dsn")>
<cfset request.dsn = '#client.dsn#'>
</cfif>..。永远不会触发(永远不会返回true)。
如果你想检查一个请求变量,那么你需要在检查之前设置它或者让需要它的代码发生。它只存在到请求的末尾。但是,您的客户端var将持续存在。也许你的意思是:
<cfif IsDefined("client.dsn")>
<cfset request.dsn = '#client.dsn#'>
</cfif>这对我来说更有意义。
更多信息
Reya -你的问题仍然是你在下面我的答案中看到的。您将需要设置您的请求变量与每个请求的意义,每次用户点击或加载的东西,导致和http调用到您的服务器。它需要在调用cfapplication之前设置,您可以在cfapplication中检查它。
如果我可以建议一个架构更改,在您的登录脚本中,找出用户属于哪个数据库,然后将其设置在会话范围中。然后将您的"datasource“属性更改为”#session.dsn“-当然,您也可以使用"client.dsn”-但这也需要上面的更改。
因此,您需要使用持久作用域(可能是会话或客户端),或者运行代码将请求作用域设置在上面粘贴的应用程序文件中的代码之前。我知道我很难说清楚。:)
发布于 2016-04-29 04:30:55
这是我的建议。对于Application.cfm中的每个case语句,只需声明dsn,如下所示:
<cfcase value="url.subdomain.here">
<cfset request.dsn = 'dsnForThisSubdomain'>
<cfset request.cfcDIR = 'cfcDirForThisSubdomain'>
</cfcase>每次请求时,总是首先运行Application.cfm代码。您不能以这种方式引用稍后在Application.cfc中运行的代码中设置的变量。这就是为什么我建议如果子域和你需要的请求变量之间存在一对一的关系,就在这里设置它们。
请注意,您可以在case语句中将多个子域作为列表放置,因此您可以:
<cfcase value="url.subdomain1.here, url.subdomain2.here">
<cfset request.dsn = 'dsnForThisSubdomain'>
<cfset request.cfcDIR = 'cfcDirForThisSubdomain'>
</cfcase>如果这对你不起作用,你需要清理代码中的一些错误和误解。首先:
<!--- Start Check for Which DB the user resides and overwrite the request.dsn variable in Application.cfm --->此时,您不能覆盖request.dsn变量。在请求生命周期中,为时已晚。你认为你能做到的假设是一个致命的缺陷。除此之外:
而不是
<cfif ((whichDB) NEQ 0 OR (whichDB) NEQ "")>
我建议使用
<cfif whichDB > 0>
这会让你的意图更清晰
<cfset whichDB = "#whichDB#">
上面的cfset只是将whichDB的值赋给它自己,您不需要这样做。您也不需要取消对var的引用来设置它。所以即使它是无用的,正确的写法应该是:
<cfset whichDB = whichDB>
顺着这条线,你就有了
<cfif (whichDB) EQ 0>
它永远不会运行,因为它嵌套在
<cfif ((whichDB) NEQ 0 OR (whichDB) NEQ "")>
所以if分支中的代码应该被移动。您可以将它放在靠近顶部的位置,在代码块的第5行的<cfset whichDB = "0">下。
至于它的其余部分,在if或elseif块的末尾不需要<cfbreak/>。如果您使用cfswitch块而不是多个elseif if块,那么这里的代码可能会更整洁,我建议使用会话作用域的var而不是客户端作用域的var。类似于:
<cfif CheckDB.RecordCount>
<cfswitch expression="#CheckDB.db#">
<cfcase value="1">
<cfset session.dsn = "xxxxx_1">
<cfset session.cfcDIR = "cfcV5">
</cfcase>
...
</cfswitch
</cfif>此时,我建议在代码库上运行搜索和替换,并将request.dsn更改为session.dsn,将request.cfcDIR更改为session.cfcDIR,如果会话变量存在,则忘记在Application.cfm文件中设置请求变量。在你的应用程序中为同一件事维护两个变量是没有价值的。但是如果你决定这样做,你必须在你的Application.cfm中得到正确的逻辑--你现在已经把它倒过来了。最好的方法是:
<cfif structkeyexists( session, 'dsn' )>
<cfset request.dsn = session.dsn >
</cfif>您还需要在session.cfcDIR的cfset周围使用类似的if语句,因为它在用户登录之前不会存在,因此会抛出一个错误。
https://stackoverflow.com/questions/36921954
复制相似问题