How to get query string from an url in coldfusion [duplicate] - coldfusion

This question already has an answer here:
ColdFusion: get url parameter by name
(1 answer)
Closed 6 years ago.
I would like to know how to get a query string from an url using coldfusion.
I have following url:
http://mypage.com/books/8540/index.cfm?current_book=215487
Now I would like to extract current_book=215487 in a var. The code below returns only the current URL.
<cfset currentURL = cgi.request_url/>

There is a scope that URL variables are stored called the URL scope (there is also one for FORM variables called FORM).
If you want to get it, you should make sure it is set, which you can do with a <cfparam> call:
<cfparam name="url.current_book" default="">
<cfset current_book = url.current_book>
Now you can use the current_book variable if you need to, or access the url.current_book variable directly like:
<cfoutput>
You chose #HTMLEditFormat(url.current_book)#
</cfoutput>
Which would output You chose 215487

Related

Why does cflocation strip characters and not visit the URL?

I have a URL stored as:
<cfset VisitURL = 'http://www.toysexample.com/search.aspx?searchBox=christmasgifts≠Sort=high&search=new' />
(The above URL string actually comes from a database field that I have no control over)
When I ask cflocation to visit the above URL like this:
<cflocation url="#EncodeForURL(VisitURL)#" addtoken="no" />
It visits the URL as a subfolder within my site. So I end up going to the URL http://www.volumeoneexample.com/http:/www.toysexample.com/search.aspx?searchBox=christmasgifts≠Sort=high&search=new
As you can see it has dropped one of the forward-slashes from the http:// part and also appended the URL as a folder within my site. I don't get why its doing this?
As mentioned in the comments, you're "over encoding". The EncodeForURL() should only be on the URL parameters.
Since you're not able to retrieve the URL and parameters separately, you might be able to get away with treating them like a list.
<cflocation url="#ListFirst(VisitURL,"?")#?#EncodeForURL(ListRest(VisitURL,"?"))#" />
If things get a little wonky you'll need to do more manipulation than that.

Why does ColdFusion create a space before the string? [duplicate]

This question already has answers here:
coldfusion weird extra space
(3 answers)
Closed 8 years ago.
I have a CFC that returns a string containing part of a URL. I want to concatenate this to the end of the domain name of the site so it makes a fully qualified URL.
However, the ColdFusion is creating a space before the concatenation. Here is how my concatenation looks:
http://www.mywebsite.com#APPLICATION.MyCFC.GetURL(urlid = url.id)#
So we have two parts:
The domain part which is just http://www.mywebsite.com
The string that's returned from the CFC which is like this /products/20
However the final output ends up like this:
http://www.mywebsite.com /products/20
So for some reason it puts a space just before concatenating the string from the CFC. I have tried to put a Trim() around the CFC invokation but it doesn't do anything.
What I have also tried to do is put the string from the CFC in a variable like this <cfset myurl = #APPLICATION.MyCFC.GetURL(urlid = url.id)#. I then concatenated this variable to the domain like this: http://www.mywebsite.com/#url# and it works fine without adding any spaces.
Why is it doing this? I don't want to keep storing the output of the CFC in yet another local variable everytime I want to use it.
This is the code from the CFC (I've left out the database stuff that it does for sake of confidentially and clarity but its essentially just this):
<cffunction name="GetURL" access="public" returntype="string">
<cfargument name="urlid" required="yes">
<cfset var result="/products/#urlid#">
<cfreturn result>
</cffunction>
add output="false" to your <cffunction> (and <cfcomponent> if it is not an UDF) may solve your problem.

Trying to dynamically output form fields returns URL values

If there is a better way to go about this (which is quite likely), please let me know how to go about it.
I'm working on some code that is supposed to dynamically set the form variables as regular variables so that we can be lazy and not have to refer to the variable with form.somevariable name.
That part works perfectly. Until I start testing for URL conflicts in which a URL variable has the same name. For instance. . .
I have a form that passes two variables; FirstName and LastName. If I hit the page, the form shows up, I input a first and last name and click submit. The code works perfectly.
However, if I have URL variables with the same names, the code reports the url variable values instead of the form values.
Some sample values;
url.FirstName = Joe
url.LastName = Black
form.FirstName = Steve
form.LastName = White
My code that exposes the form variable will correctly find the form field names, but then when I 'evaluate' the value of the given form field, it will return the value of the URL variable of the same name rather than the form variable.
What I am really wanting (as I described briefly up above) is to have code that automatically converts client, URL and Form variables into 'regular variables' so that you don't have to write lots of extra code grabbing them later on. Frameworks like CFWHEELS and ColdBox do this by default, but at the company I work out, we aren't using any of them. I need it to expose the URL variables, but give presidence to form variables if they have the same name, because they are likely to be intended to do an update or such.
The code follows Feel free to ignore the code for the URL and client variables if you wish as they don't directly affect how the form code works, I have tested with them commented out and I get the same result. I provided all of it to give a more complete idea of what I have been toying with so far. Please note that I don't normally use 'evaluate'. There is probably a better way to go, but I don't know what it is.
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++
First Name
Last Name
URL variables:
<cfloop index="i" list="#paramsurl#">
<cfset myDynVar = Evaluate(i)>
<!--- Let's output the dynamically created variable as a test --->
#i# = #myDynVar#<br />
</cfloop>
<cfoutput>
<b>Field Names:</b> #Form.FieldNames#
<p>
<b>Field Values:</b><br>
<cfloop INDEX="TheField" list="#Form.FieldNames#">
#TheField# = #Evaluate(TheField)#<br>
<cfset TheField = Evaluate(TheField)>
</cfloop>
</p>
Lets try and output the two form fields without using the "form." notation<br>
FirstName : #FirstName# <br />
LastName : #LastName#
</cfoutput>
The client variables currently available are:
<cfset nVarCounter = 1>
<cfloop list="#GetClientVariablesList()#" index="whichClientVar">
#whichClientVar# : #client[whichClientVar]#<br />
<cfset whichClientVar = Evaluate(whichClientVar)>
</cfloop>
You should always scope your variables. When you use evaluate it runs through the scope order and it pulls the values out of the url scope before it gets to the form scope
You can use associative array notation to pull the data (as seen below).
<cfoutput>
<b>Field Names:</b> #Form.FieldNames#
<p>
<b>Field Values:</b><br>
<cfloop INDEX="TheField" list="#Form.FieldNames#">
#TheField# = #form[TheField]#<br><!--- specify form scope --->
<cfset myField = structKeyExists(url,TheField) ? url.TheField : form.TheField>
</cfloop>
</p>
</cfoutput>
You can 'copy' the values from form scope and url scope into the variables scope by using structAppend().
structAppend( variables, form, true );
structAppend( variables, url, false );
In the first line, any element of the form scope is copied to the variables scope and if a variable already exists with the same name in variables scope, it will overwrite that value with the value from the form scope.
In the second line, elements form URL scope are copied to variables scope but if a variable already exists in the variables scope, it is NOT overwritten.
You can do this for ANY scope and any other ColdFusion structure. You can also reorder them so that one scope has precedence over the others.
In CF 10 or Railo 4, you could use the defaults() function of the Underscore.cfc library to succinctly accomplish what you're trying to do. Example:
// instantiate Underscore library
_ = new Underscore();
// copy values from form and url scopes into the variables scope
_.defaults(variables, form, url);
This function "fills in" any undefined values in the first struct to the values in the subsequent structs. It works from left to right, so in this example it gives precedence to values in form over the values in url.
Disclaimer: I wrote the Underscore.cfc library.
Please refer to the following Adobe documentation for order of precedence:
http://help.adobe.com/en_US/ColdFusion/9.0/Developing/WSc3ff6d0ea77859461172e0811cbec09af4-7fdf.html
If you want to reverse this precedence for some reason you should be able to just set all of your FORM fields into the variables scope...
Maybe something like ...
<cfloop collection=#form# item="varName">
<cfset SetVariable("variables.#varName#", evaluate("FORM." & varName))>
</cfloop>
Thanks for all of the great ideas.
Following is what I ended up going with.
<cfset scopes = "url,client,form">
<cfloop list="#scopes#" index="i">
<cfloop list="#structKeyList( evaluate( i ) )#" index="j">
<cfset structInsert( VARIABLES, j, evaluate( i & '["' & j & '"]' ), true ) />
</cfloop>
</cfloop>
<cfoutput>
Lets try and output the two form fields without using the "form." notation and make sure that the URL variables are NOT over writing the Form ones<br>
FirstName : #FirstName# <br />
LastName : #LastName#<br />
</cfoutput>
<cfdump var="#VARIABLES#" abort="1" label="Combined Variables Scope stuff" />

ColdFusion, Setting a POST variable

Im editing my first ColdFusion script .... I have a form which has <input type="hidden" name="name" value="1">.
On the processing page i want to take that value and set it as a POST variable so i can send it onto another page.
I know how to do it in PHP, like so
$_POST['somename'] = $_POST['name']
How would i do that in CF?
Following the idiom in your php code, you can do something like this:
<cfset form['somename'] = form['name']>
...or, if in cfscript:
form['somename'] = form['name'];
If you're concerned about the existence of the variable, you can precede the assignment with <cfparam>:
<cfparam name="form.name" default=""><!--- assuming blank ok as default --->
<cfset form['somename'] = form['name']>
...or in script:
param name='form.name' default='';
form['somename'] = form['name'];
Of course you can also wrap the assignment in a conditional:
if( structkeyexists(form,'name') ){
form.somename = form.name; // dot notation alternative to bracket syntax
}
This all begs the question of what exactly you're trying to achieve with this approach.
The ColdFusion syntax is similar. "Post" variables are available in the system structure FORM, and "Get" variables in the system structure URL. Like in PHP, values can be accessed using associative array notation. You can also use dot notation (for valid field names)
<cfset otherVariable = FORM["variableName"] >
<cfset otherVariable = FORM.variableName >
i want to take that value and set it
as a POST variable so i can send it
onto another page.
I am not quite sure what you mean there. Typically, you do not need to reassign FORM or URL values. You simply reference the variable in your code.
<cfoutput>
Go To Other Page
</cfoutput>
You can try this by checking if the post variable is set and then storing it with scope of FORM.
<cfif isdefined ("FORM.name")>
<cfset FORM.somename="#FORM.name#">
</cfif>

How Can I get the URL parameter & Value in Coldfusion?

How Can I get the URL parameter & Value in Coldfusion?
for Ex:-
my URL is
test.cfm?par1=val1&par2=val2&par3=val3
Is it possible to get the second parameter and its value directly?
with <cfset param='#url.par2#'> I can get value of par2,
But my parameters are dynamicically generated from other page and passed to here (par2 may be next time abc2,xyz2 etc..)
So I think better way is to get the parameter and Value in 2nd Possition(Possition dont change always).
Any Idea How can I get it ?
Thanks in advance
You can also access the url scope as a struct, so you could get:
<cfset param2 = url['param2'] />
This is useful if you might have a naming convention for a bunch of fields. Say you're collecting names and emails like so:
email1=foo#bar.com&name1=Fred&email2=xxx#yyy.com&name2=Sally
You could write something like:
<cfloop condition="someCondition">
<cfset email = url['email' & i] />
<cfset name = url['name' & i] />
<!--- Do something --->
<cfset i++ />
</cfloop>
<cfset Param2 = ListGetAt(CGI.QUERY_STRING,2,"&")>
Order of query string variables is not relevant, or your app shouldnt expect it to be relevant. I think your best bet is to have another variable which is a list of the variables in the order. Like so:
test.cfm?par1=val1&par2=val2&par3=val3&list=var1,var2,var3
Notice the presence of the new variable "list".
So you first grab the value of "list" and then takes it 2nd entry "var2" and reference that in the URL scope. You could easily abstract all of this so the names of the variables themselves dont matter. Good error handling will be necessary to guard against missing expectations.
to get the list of params you can use structKeyList(url) or structKeyArray(url) then access those parameters through the url scope like #url['par1']#
<cfset params = structKeyList(url) />
<cfdump label="parameters" var="#params#" />
<cfloop index="ix" list="#params#">
<cfoutput><div>#ix# = #url[ix]#</div></cfoutput>
</cfloop>
as others have mentioned, you really shouldn't rely on the order of parameters
<cfscript>
par2=getToken(cgi.query_string,2,"&"); // contains "par2=val2"
par2name=getToken(par2,1,"="); // contains "par2"
par2value=urlDecode(getToken(par2,2,"=")); // contains "val2"
</cfscript>
You could also use the listGetAt function, which is basically equivalent to getToken, with slightly different syntax.