2009-06-09 67 views
2

我在我公司的站點中有一個函數,它使用cgi.remote_host變量調用hostip.info提供的API並返回orgin的國家/地區。這是應該的工作方式是:在ColdFusion中調用遠程API有時會導致超時

  • 功能從API發現全國各地,
  • 有違我們的本地數據庫查詢,以確定我們要轉送 用戶哪些網站,
  • 將用戶重定向到相應的站點。

如果出於任何原因,我們無法將某個國家與我們的某個地區關聯,我們會將該用戶重定向到默認網站。

什麼實際上發生的是,偶爾,我們的服務器無法找到API,我們得到超時錯誤。

這是我們呼籲得到境內功能的代理:

<cffunction name="getGeoInfo" access="public" output="true" returntype="any" hint="call getGeoIP API and check country against DB"> 
    <cfargument name="IPAddress" required="yes" type="string" /> 

    <!--- Calling hostip API to get our Geo IP information ---> 
    <cfhttp url="http://api.hostip.info/?ip=#arguments.IPAddress#" method="get" result="geoIP" /> 

    <!--- Try to parse the file, if it can't parse, we don't create the variable ---> 
    <cftry> 
     <cfset geoIPXML = xmlParse(geoIP.fileContent) /> 
    <cfcatch type="any" /> 
    </cftry> 

    <!--- If variable was created, perform the function to get territory info ---> 
    <cfif isDefined("geoIPXML")> 
     <cfset countryAbbrev = geoIPXML.HostipLookupResultSet['gml:featureMember']['hostip']['countryabbrev'].xmlText /> 

     <cfquery name="theTerritory" datasource="#request.dsource#"> 
      SELECT territory 
      FROM countries 
      WHERE countryCode = <cfqueryparam value="#countryAbbrev#" cfsqltype="cf_sql_varchar" /> 
     </cfquery> 

     <!--- If no record was found, set locale to default ---> 
     <cfif theTerritory.recordcount EQ 0> 
      <cfset returnLocale = "default" /> 
     <cfelse> 
      <!--- Otherwise set it to territory found in DB ---> 
      <cfset returnLocale = theTerritory.territory /> 
     </cfif> 
    <cfelse> 
    <!--- if no XML file was returned, set locale to default ---> 
     <cfset returnLocale="default" /> 
    </cfif> 

    <cfreturn returnLocale /> 
</cffunction> 

缺少什麼我在這裏?我應該如何改變這個函數,以便如果http請求超時,我仍然返回我的默認值?

回答

6

包裹<cfhttp>呼叫<cftry>

另外,我想有catch塊只返回defaultLocale,而不是什麼都不做,然後檢查geoIPXML的存在。

<cftry> 

    <cfhttp url="http://api.hostip.info/?ip=#arguments.IPAddress#" 
      method="get" 
      result="geoIP" 
      throwOnError="yes" /> 
    <cfset geoIPXML = xmlParse(geoIP.fileContent) /> 

<cfcatch type="any"> 
    <cfreturn "default"> 
</cfcatch> 

</cftry> 
+1

這很明顯。我應該想到會這樣做。謝謝。 – 2009-06-09 18:24:57

2

我不太確定您的超時時間僅適用於http調用,還是作爲整個頁面。 CFHTTP有一個超時屬性。如果您的http呼叫超時,您可以使用它來防止您的網頁超時。

使用try/catch(如Patrick所示)返回默認結果。

+0

超時時間是針對HTTP調用的,返回的錯誤消息是「該請求已超出HTTP請求所在行的允許時間限制標記:cfhttp」。 – 2009-06-11 13:17:00

2

無論哪種方法是有效的,但不是在try catch塊包裹你的電話,你可以設置在< CFHTTP>呼叫

throwOnTimeout="false" 

屬性並沒有作出任何其他附加修改您的碼。 cfhttp結構將返回幷包含「fileContent」變量,但將填充「Connection Timeout」。試圖xmlParse它會失敗,然後執行將擊中你的catch塊。我會推薦Patrick在你的catch塊中使用< cfreturn「default」/>,這樣你的程序的其餘部分就不必隨意執行了。