Why is% 26 decoded and passed as a parameter to the JavaScript function from the link?

We have a menu in a web application that uses <a> tags to load pages into the main frame.

A typical menu item would be something like:

 <a target="mainframe" href="/servlet1?param1=val1&parma2=servlet2?s2p1=val2%26s2p2=val3&param3=val4">Menu Item 1</a> 

We needed to add some JavaScript validation before requesting a link, so I changed it to:

 <a target="mainframe" href="javascript:validate('/servlet1?param1=val1&parma2=servlet2?s2p1=val2%26s2p2=val3&param3=val4')">Menu Item 1</a> 

(I know that javascript:function in a link is bad practice, but we use a third-party library to create the menu so that I cannot change this part of the code)

Servlet1 expects:
param1 = 'val1'
param2 = 's2p1 = val2% 26s2p2 = val3 servlet2?
param3 = 'val4'

Servlet1 will then go to param2, so Servlet2 expects:
s2p1 = 'value2'
s2p2 = 'val3'

However, when I put alert in my check function to check what was passed:

 function validate(href) { alert(href); ...validation code... } 

He gives:
/ servlet 1? param1 = val1 & parma2 = servlet2? s2p1 = val2 ** & ** s2p2 = val3 & param3 = val4 (note the bold & , which was %26 in the above function call)

%26 converts to & when it is passed to the JS function, which normally will not be executed until the request is redirected to Servlet2 . Since %26 has already been changed to & , the request parameter s2p2 gets the value servlet1 instead of Servlet2 .

Basically, my question is why %26 converts to & at this point, just passing it as a function parameter from the href attribute if you do onClick="validate('/servlet1?param1=val1&parma2=servlet2?s2p1=val2%26s2p2=val3¶m3=val4')"
it remains as %26 , as you expected?

+4
source share
3 answers
 <a target="mainframe" href="javascript:validate('/servlet1?param1=val1&parma2=servlet2?s2p1=val2%26s2p2=val3&param3=val4')">Menu Item 1</a> 

Urgh. You have a URL embedded in the URL, all embedded in a different URL! These are too many escape levels for the human mind to handle. It:

 javascript:validate('/servlet1?param1=val1&parma2=servlet2?s2p1=val2%26s2p2=val3&param3=val4') 

is itself a URL. Although pseudo-url is javascript: which you should never use. It is decoded by the JavaScript command:

 validate('/servlet1?param1=val1&parma2=servlet2?s2p1=val2&s2p2=val3&param3=val4') 

at this point you have already lost% 26. Now that you use this as the url itself, it will fail.

Avoid multiple coding issues by moving the script to a JavaScript block (or external script) instead of the HTML attribute:

 <a target="mainframe" class="validateme" href="/servlet1?param1=val1&amp;parma2=servlet2?s2p1=val2%26s2p2=val3&amp;param3=val4">Menu Item 1</a> 

(Note that HTML escaping ampersands is also required here.) Then from a script, execute:

 // find 'validateme' links and add event handler // for (var i= document.links; i-->0;) if (document.links[i].className==='validateme') document.links[i].onclick= validate; 

Then, in your validation function, simply return true if everything is ok and you want the link to be executed, or false to stop it.

+8
source

No, %26 (correctly) interpreted as and when the HTML file is first read in the browser, and not when passed to the JavaScript function. If you need the literal character sequence β€œpercent two six,” you must encode this as %2526 .

+4
source

The javascript: protocol javascript: is still considered a valid URL, so the browser encodes it correctly. Its easy to decode in your Javascript ...

 alert(decodeURIComponent(href)); 
0
source

All Articles