问题
I'm new to matrix parameter and I know CF10 can access them through their new RESTful API support.
However, is there a way to access these parameters without using RESTful API support?
E.g. http://moremaps.com/map/color.cfm;lat=50;long=20;scale=32000
回答1:
You can use:
color.cfm;lat=50;long=20;scale=32000
Then get the param string with:
ListRest(getPageContext().getRequest().getRequestUri(),';')
This worked back in CFMX - it's not specific to CF10 or part of the RESTful API, and is available due to the servlet container (Tomcat/Jrun/etc) following the servlet spec with the ability to get the original URL.
(And you can of course use URL rewriting to hide the .cfm from the user.)
There isn't a matrix scope because CF hasn't implemented it fully - it is done as part of REST webservices, (where it's as an argument with the appropriate RestArgSource
attribute). Only the CF team can say why they designed it that way.
However, you can easily create your own scope/struct like so:
var MatrixString = ListRest(getPageContext().getRequest().getRequestUri(),';');
var Matrix = {};
for ( var CurParam in ListToArray(MatrixString,';') )
Matrix[ UrlDecode( ListFirst(CurParam,'=') ) ] = UrlDecode( ListRest(CurParam,'=') );
(Obviously, remove the var scoping if not using inside a function.)
That works both directly and via IIS, and should work fine on other servers too, even where path_info may have been modified.
Update: This answer is incomplete/inaccurate.
Reading up further on matrix params, they can actually appear at any point in the request_uri (the entire part after the host_name, before the query_string) - that is, both script_name and path_info can contain parameters, without affecting their final value.
To clarify this, both these URLs:
htp://domain.com/a/b.cfm/c/d http://domain.com/a;alpha=1/b.cfm;beta=2/c;gamma=3/d;delta=4
Result in these CGI vars:
script_name = /a/b.cfm path_info = /c/d
(Except in IIS, where path_info is incorrectly implemented.)
Obviously extracting and acting upon these properties is more complex than the code above - I'll update this answer again once I've made sure I understand them more fully.
In the meantime, here's a couple of potential options - the first returns a struct of params if a path element has one, the second returns an array containing every path element - whether either of these are suitable will depend on how the matrix params are to be used:
<cffunction name="getMatrixStruct" returntype="Struct" output=false
hint="Returns struct with item for each path element with params"
>
<cfargument name="RequestUri" type="String" required hint="The non-host and non-querystring part of a URL." />
<cfscript>
var Result = {};
for ( var CurSegment in ListToArray(RequestUri,'/') )
{
var SegName = UrlDecode( ListFirst(CurSegment,';') );
for ( var CurParam in ListToArray(ListRest(CurSegment,';')) )
Result[SegName][UrlDecode( ListFirst(CurParam,'=') ) ] = UrlDecode( ListRest(CurParam,'=') );
}
return Result;
</cfscript>
</cffunction>
<cffunction name="getMatrixArray" returntype="Array" output=false
hint="Returns array of structs for all path element, with any parameters included."
>
<cfargument name="RequestUri" type="String" required hint="The non-host and non-querystring part of a URL." />
<cfscript>
var Result = [];
var Pos = 0;
for ( var CurSegment in ListToArray(RequestUri,'/') )
{
Result[++Pos] = { 'Name' = UrlDecode( ListFirst(CurSegment,';') ) };
for ( var CurParam in ListToArray(ListRest(CurSegment,';')) )
Result[Pos][UrlDecode( ListFirst(CurParam,'=') ) ] = UrlDecode( ListRest(CurParam,'=') );
}
return Result;
</cfscript>
</cffunction>
回答2:
You can access it via cgi.path_info
. For example:
http://localhost/myApp/index.cfm;this=that;pet=cat
Becomes
cgi.PATH_INFO=/MyApp/index.cfm;this=that;pet=cat
Then you can
struct function getMatrix() output="false" {
var arURLData = ListToArray(cgi.path_Info, ";");
var stData = {};
if (arrayLen(arData) <= 1) {
return stData;
}
for(var i = 2; i <= ArrayLen(arData); i++) {
// setVariable("stData.#listfirst(arURLData[i], "=")#", listlast(arURLData[i]);
stData[listfirst(arURLData[i], "=")] = getToken(arURLData[i], 2, "=");
}
return stData;
}
You will probably want to add some code to protect against URL injection attacks.
来源:https://stackoverflow.com/questions/19253722/is-it-possible-to-access-the-matrix-parameters-name-value-pair-separated-by-sem