I have a Spring-MVC application with Freemarker as the view component.
In my templates, several links are generated which point back to my application and which include URL parameters containing a hash key (#).
Example:
parameter: Q#106368 11
URL generated by Freemarker with encoded param: testurl.html?key=Q%23106368%2011
I use JavaScript to redirect to this URL (reason: I use JS to manage loading of 2 frames at the same time).
The redirect method is simple:
function redir(url) {
window.location.href = url;
}
The JS call generated by Freemarker looks like
test
My problem is that the browser / Javascript converts back the URL encoded parameter, thinks there is a # and cuts off there.
When I use window.location.href='http://...' directly it works. Only when using the method parameter it seems to be magically URL decoded and then the redirect fails because the URL gets cut off at the #.
Is there an easy way to transmit the parameter correctly?
I am aware that I could replace the #, e.g. with $$$hash$$$, in the template and do the replacement on the server side again. But there are so many places I would have to change...
As Marc B commented, it is necessary to URL encode again. The method would be encodeURI(). However, this method does not encode the # sign. For my specific use case, I have to replace the # sign with %23 after the encoding.
The redirect JS method finally looks like:
function redir(url) {
url = encodeURI(url);
url = url.replace(/#/g, '%23');
window.location.href = url;
}
Comparing escape(), encodeURI(), and encodeURIComponent()
encodeURIComponent/decodeURIComponent is more thorough than just encodeURI, it will decode/encode '#' and event '/'
What browser are you using? I'm trying FireFox 5 and it doesn't convert %23 back into # in my testing. When you mouse over the link or copy the link location, what does that have? Are you sure whatever is outputting the link isn't doing the conversion?
Update
This isn't ideal, but it seems like it solves the problem:
<a onclick="url = 'http://localhost:8080/testappp/testurl.html?key=Q%23106368%2011';" href="javascript:redir(url);">test</a>
It seems like the href attribute is decoded. When I mouse over it I seen the # instead of the %23.
Related
If I pass a string as "testabc#" it breaks somewhere on the way route to the controller. I'm not sure why the # is causing me the issue. Is this a key work in JavaScript causing the issue? I have tried all other different specials characters and they work just fine. Has anyone else come across this issue.
`/api/Controller/UpdatePassword?currentPassword=${currentPassword.value}&newPassword=${newPassword.value}&confirmPassword=${confirmPassword.value}`,
Anchor (#) is a feature of URL called fragment and it is used for internal page references. Using a question mark (?) and ampersand (&) can break your HTTP request like an anchor does because all of these things are URL features and it changes URL behavior.
To avoid this kind of error you must use encodeURI() or encodeURIComponent() like below:
with encodeURIComponent():
var url = `/api/Controller/UpdatePassword?currentPassword=${encodeURIComponent(currentPassword.value)}&newPassword=${encodeURIComponent(newPassword.value)}&confirmPassword=${encodeURIComponent(confirmPassword.value)}`
with encodeURI():
var url = encodeURI(`/api/Controller/UpdatePassword?currentPassword=${currentPassword.value}&newPassword=${newPassword.value}&confirmPassword=${confirmPassword.value}`)
# in a url is a special character which indicates a "fragment", which means a special part of the url which is an anchor in the page, of sorts. Thats why it breaks your code. ? And & are also special, and so are a few others.
You should url encode data that you pass in the url.
Try use encodeURI() to the url string before fetching, like:
var url = `/api/Controller/UpdatePassword?currentPassword=${currentPassword.value}&newPassword=${newPassword.value}&confirmPassword=${confirmPassword.value}`
encodeURI(url)
JS fiddle created at https://jsfiddle.net/ankitwasankar/sc50ecyf/ demonstrates, how the url sent as a parameter decode itself inside function. Is it the expected behaviour. Do I need to encode url passed as parameter again inside function. Currently when URL is opened with window.location.href it doesn't contain %26 instead contains &. So on server, HttpServletRequest.getParameterNames() returns two parameters instead of one.
What about split %26 in-between, like:
<a href='javascript:print_me("https://www.google.co.in/search?query=a%2" + "6b=26")'>Click</a>
This prevents the auto-decoding, although it's a little bit hacky.
I'm doing some work with a chrome extension that needs to use the google chrome results URLs, which are redirects, and convert those to ordinary URLs for use.
Examples:
me Googling Google: https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&uact=8&ved=0ahUKEwi6w8WR4ZzSAhUZHGMKHRntAv0QFggaMAA&url=https%3A%2F%2Fwww.google.com%2F&usg=AFQjCNFePWT_Lkni-D9ikX7wC3eYuDMQYQ&sig2=gPD7xuE6nstkxWFhSh2QLQ&bvm=bv.147448319,d.cGw
What I want: https://www.google.com
I've tried using string.split().pop(), but that just used EVERYTHING after the inputted text. For a basic example, I want a way to reliably turn testHItestBYE into HIBYE. What would be the best way to do this?
Redirect URLs seem to have target URL in the url parameter, so we can split the string using '&url=' as delimiter, pop the last element, split it using '&' as the delimiter, get the first element. It is URL-encoded, so we'll have to decode it.
var findURL = function findURL(url){
return decodeURIComponent(url.split('&url=').pop().split('&')[0]);
}
//example call
result = findURL( 'https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&uact=8&ved=0ahUKEwi6w8WR4ZzSAhUZHGMKHRntAv0QFggaMAA&url=https%3A%2F%2Fwww.google.com%2F&usg=AFQjCNFePWT_Lkni-D9ikX7wC3eYuDMQYQ&sig2=gPD7xuE6nstkxWFhSh2QLQ&bvm=bv.147448319,d.cGw' );
console.log(result);
There are other ways to do it.
I have an MVC application that makes an API call in an onclick event
#Model.MyApiCall is a string that looks something like this:
window.location = 'http://localhost/myPath?myImagePath=http://myimagepath&width=360&category=2'
This successfully calls my API. So far so good.
However, for some reason everything after & is getting cut off from myImagePath. So instead of myImagePath equaling what was sent from my click, I'm only getting this:
http://myimagepath
You have to encode your query string parameter. You can do it in javascript:
window.location = 'http://localhost/myPath?myImagePath=' + encodeURIComponent('http://myimagepath') + '&width=360&category=2'
using encodeURIComponent.
You can also do it inside your MVC controller using HttpUtility.UrlEncode only on the http://myimagepath part of your Model.MyApiCall.
[Edit]
If your myImagePath parameter is the entire http://myimagepath&width=360&category=2 string then of course Steve Danner is right and you should follow his answer.
The ampersand (&) is a special character and needs to be encoded to be properly parsed by the browser. You'll need to break up your query string and actual path into separate strings. Something like this:
<a href="javascript://" onclick="#(Model.MyApiCallPath +
HttpUtility.UrlEncode(Model.MyApiCallQueryString))"></a>
Your final js will look something like:
window.location = 'http://localhost/myPath?myImagePath=http%3A%2F%2Fmyimagepath%26width%3D360%26category%3D2';
You are trying to pass a url as a url parameter. Since the url in question contains special characters, you need to escape/encode the uri components.
Since you're using ASP.Net, you should wrap the string with:
window.location = Uri.EscapeUriString('http://localhost/myPathmyImagePath=http://myimagepath&width=360&category=2')
I have a GET request that takes a parameter, this parameter is also a URL. So normally I just encode the URL and then decode it in my server, this works pefectly from Java, but now I am on jQuery and I have a problem with it.
This is the value of that parameter:
http://www.BookOntology.com/bo#ania
When I encode it like this:
encodeURI(userURI)
I get the same value, while i thought that i should have gotten this
http%3A%2F%2Fwww.BookOntology.com%2Fbo%23ania
To show you what is the wrong
My current approach (which is using econdeURI) brings this final URL (note that I just want to encode the paramter not the whole URL).
http://bla bla bla?userURI=http://www.BookOntology.com/bo#ania
But in the server when i read the value of the userURI parameter i get:
http://www.BookOntology.com/bo
It is definitely a problem with the way i encode that value of that parameter because, again, the value after and before encoding is the same though the value contains some characters that should be changed.
Could you help me pass that please?
Try with encodeURIComponent function , which encodes a Uniform Resource Identifier (URI)
DEMO: encode input value
Read the MDN DOCS for more info.
encodeURI only changes characters that can't appear in a URL at all.
You're looking for encodeURIComponent which encodes all characters with special meaning in a URL as well (and makes it suitable for inserting in a query string).