104 lines
4.8 KiB
Plaintext
104 lines
4.8 KiB
Plaintext
<cfsilent><!--- утилита для передачи стека вызовов через URL --->
|
||
<!---v1.01 14:00 03.04.2019 added output param thisURL--->
|
||
<!---v1.02 06:16 26.12.2019 symbols -._ are not encoded --->
|
||
|
||
<cfparam name="ATTRIBUTES.thisUrl" type="string" default=""><!--- текущий URL без трэка --->
|
||
<cfparam name="ATTRIBUTES.output" type="string" default="tr">
|
||
<cfparam name="ATTRIBUTES.input" type="string" default="track"><!--- имя параметра в URL или FORM, в которой лежит текущий трэк --->
|
||
<cfparam name="ATTRIBUTES.urlParamName" type="string" default="#ATTRIBUTES.input#">
|
||
<cfparam name="ATTRIBUTES.defaultBackUrl" type="string">
|
||
|
||
<!---<cffunction name="urlSafeWrap">
|
||
<cfargument name="s" type="string"/>
|
||
<cfreturn replace(URLEncodedFormat(s), "%", "!", "ALL")/>
|
||
</cffunction>--->
|
||
<!---<cffunction name="urlSafeWrap">
|
||
<cfargument name="s" type="string"/>
|
||
<cfreturn
|
||
replace(
|
||
replaceList(
|
||
URLEncodedFormat(s),
|
||
"#URLEncodedFormat('_')#,#URLEncodedFormat('.')#,#URLEncodedFormat('-')#,#URLEncodedFormat('~')#,#URLEncodedFormat('=')#",
|
||
"_,.,-,~,="
|
||
),
|
||
"%", "!", "ALL"
|
||
)/>
|
||
</cffunction>--->
|
||
|
||
<cffunction name="urlSafeWrap">
|
||
<cfargument name="s" type="string"/>
|
||
<cfreturn
|
||
replace(
|
||
replaceList(
|
||
URLEncodedFormat(s),
|
||
"#URLEncodedFormat('_')#,#URLEncodedFormat('.')#,#URLEncodedFormat('-')#",
|
||
"_,.,-"
|
||
),
|
||
"%", "!", "ALL"
|
||
)/><!---unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" https://www.ietf.org/rfc/rfc3986.txt--->
|
||
</cffunction>
|
||
|
||
<cffunction name="urlSafeUnWrap">
|
||
<cfargument name="s" type="string"/>
|
||
<cfreturn URLDecode(replace(s, "!", "%","ALL"))/>
|
||
</cffunction>
|
||
|
||
|
||
<cfif StructKeyExists(form, ATTRIBUTES.input)>
|
||
<cfset track=structFind(form, ATTRIBUTES.input)/>
|
||
<cfelseif StructKeyExists(url, ATTRIBUTES.input)>
|
||
<cfset track=structFind(url, ATTRIBUTES.input)/>
|
||
<cfelse>
|
||
<cfset track=""/>
|
||
</cfif>
|
||
|
||
<!--- для предохранения спецсимволов (особенно запятых) в урле используется заворачивание в URLEncodedFormat. ColdFusion (по крайней мере старые версии) не умеет возвращать множественные значения иначе, как списком через запятую. Чтобы избежать непрошенного разворачивания URLEncodedFormat при отправке GETом, мы заменяем % на !.
|
||
Реализовал вариант с заворачиванием в GZIP, работает неплохо, но вариант с URLEncodedFormat сохраняет хоть какую-то читабельность.
|
||
Можно было бы кодировать в base64. Или вообще хранить на сервере в сессии, а передавать хэш - но непонятно, когда можно забыть этот урл, а накапливать их зря в сессии не хочется.
|
||
Попробовал Base64 - очень плохо, все размножается при повторном кодировании и начинает виснуть.
|
||
--->
|
||
|
||
<cfset trackBack="">
|
||
|
||
<cfif listLen(track) GT 0>
|
||
<cfset trackBack=ListDeleteAt(track, listLen(track))>
|
||
</cfif>
|
||
|
||
<cfset trackForward=ListAppend(track, urlSafeWrap(ATTRIBUTES.thisUrl))/>
|
||
<cfset backUrlBase=urlSafeUnWrap(listLast(track))/>
|
||
|
||
<cfif len(backUrlBase) GT 0>
|
||
<cfif len(trackBack) GT 0>
|
||
<cfif find("?", backUrlBase) GT 0>
|
||
<!--- has query string --->
|
||
<cfset backUrl="#backUrlBase#&#ATTRIBUTES.urlParamName#=#trackBack#"/>
|
||
<cfelse>
|
||
<!--- no query string --->
|
||
<cfset backUrl="#backUrlBase#?#ATTRIBUTES.urlParamName#=#trackBack#"/>
|
||
</cfif>
|
||
<cfelse>
|
||
<cfset backUrl="#backUrlBase#"/>
|
||
</cfif>
|
||
<cfelse>
|
||
<cfset backUrl="#ATTRIBUTES.defaultBackUrl#"/>
|
||
</cfif>
|
||
|
||
<cfif NOT (find("?", ATTRIBUTES.thisUrl) GT 0)>
|
||
<cfset selfUrl="#ATTRIBUTES.thisUrl#?#ATTRIBUTES.urlParamName#=#track#"/>
|
||
<cfelse>
|
||
<cfset selfUrl="#ATTRIBUTES.thisUrl#&#ATTRIBUTES.urlParamName#=#track#"/>
|
||
</cfif>
|
||
|
||
<cfset setVariable("CALLER.#ATTRIBUTES.output#", structNew())/>
|
||
<cfset setVariable("CALLER.#ATTRIBUTES.output#.fw", trackForward)/><!--- значение стэка: &track=#tr.fw# --->
|
||
<cfset setVariable("CALLER.#ATTRIBUTES.output#.fwx", "#ATTRIBUTES.urlParamName#=#trackForward#")/><!--- готовый суффикс для URL: &#tr.fwx#--->
|
||
<cfset setVariable("CALLER.#ATTRIBUTES.output#.bk", trackBack)/>
|
||
<cfset setVariable("CALLER.#ATTRIBUTES.output#.backUrl", backUrl)/>
|
||
<cfset setVariable("CALLER.#ATTRIBUTES.output#.self", track)/>
|
||
<cfset setVariable("CALLER.#ATTRIBUTES.output#.selfUrl", selfUrl)/>
|
||
<cfset setVariable("CALLER.#ATTRIBUTES.output#.thisUrl", ATTRIBUTES.thisUrl)/>
|
||
<cfset setVariable("CALLER.#ATTRIBUTES.output#.len", listLen(track))/>
|
||
|
||
<cfexit method="exitTag"/>
|
||
</cfsilent>
|