0

好的,由于某些奇怪的原因,我创建的 request.dsn 和另一个名为 request.cfcDIR 的变量一旦在 Application.cfm 文件中设置就不会被保留。(Coldfusion 10)

这是上述两个变量的值的来源。

<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>

因此,当用户转到定义用户页面登陆时,我收到一条错误消息,指出“请求中未定义元素 DSN”,这是胡说八道,因为正在定义。(Coldfusion 10)

4

2 回答 2

3

“请求范围”存在于单个请求的整个生命周期中。除非您的<cfapplication ...>标签上方有任何内容,否则该行显示:

<cfif IsDefined("request.dsn")>
        <cfset request.dsn = '#client.dsn#'>
      </cfif>

... 永远不会触发(永远不会返回 true)。

如果你想检查一个请求变量,那么你需要要求它被设置或者在检查之前有需要它的代码。它只存在到请求结束。但是,您的客户端变量将持续存在。也许你的意思是:

<cfif IsDefined("client.dsn")>
        <cfset request.dsn = '#client.dsn#'>
      </cfif>

这对我来说更有意义。


附加信息

Reya - 你的问题仍然是你在我的回答中看到的。您需要为每个请求设置您的请求变量,这意味着每次用户单击某些内容或加载导致您的服务器的 http 调用时。 它需要在调用您检查它的 cfapplication 之前设置。

如果我可以建议进行架构更改,请在您的登录脚本中确定用户所属的数据库,然后将其设置在会话范围内。然后将您的“数据源”属性更改为#session.dsn” - 或者您当然可以使用“client.dsn” - 但这也需要进行上述更改。

因此,您将需要使用持久范围(可能是会话或客户端)或运行代码以在您上面粘贴的应用程序文件中的代码之前设置请求范围。我知道我很难说清楚。:)

于 2016-04-28T18:13:00.033 回答
0

这是我的建议。对于 Application.cfm 中的每个 case 语句,只需声明 dsn,如下所示:

<cfcase value="url.subdomain.here">
  <cfset request.dsn = 'dsnForThisSubdomain'>
  <cfset request.cfcDIR = 'cfcDirForThisSubdomain'>
</cfcase>

Application.cfm 代码将始终在每个请求上首先运行。您不能以这种方式引用稍后将在 Application.cfc 中运行的代码中设置的变量。这就是为什么我建议如果子域和您需要的请求变量之间存在一对一的关系,只需在此处设置它们。

请注意,您可以在案例语句中将多个子域作为列表放置,因此您可以:

<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 分支中的代码。<cfset whichDB = "0">您可以将其放在代码块第 5 行下方的顶部附近。

至于它的其余部分,在or块<cfbreak/>的末尾不需要。如果您使用 cfswitch 块而不是多个 elseif 块,您的代码可能会更清晰,并且我建议使用会话范围的 var 而不是客户端范围的 var。就像是:ifelseif

<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 文件中设置请求变量变量存在。在您的应用程序中为同一事物维护 2 个变量没有任何价值。但是如果你决定这样做,你必须在你的 Application.cfm 中得到正确的逻辑——你现在把它倒过来了。最好是:

<cfif structkeyexists( session, 'dsn' )>
    <cfset request.dsn = session.dsn >
</cfif>

并且您还需要围绕 session.cfcDIR 的 cfset 的类似 if 语句,您有一个 client.cfcDIR,因为它在用户登录之前不存在,因此会引发错误。

于 2016-04-28T20:30:54.953 回答