Passing URL as string -- everything after '&' gets lost - javascript

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')

Related

JavaScript fetch API call with string interpolation with string contains # always null

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)

Passing encoded url as parameter javascript function

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.

Slash interpolation in JS

I have got the following url:
'/aaa/bbb/ccc/' + part + '/ddd/eee'
part is variable which contains '/'. I need to interpolate it, because Rails backend catches this route as incorrect (404 error), but part value must be just part or URL. How can I do it? Thanks in advance!
You need to encode this url to make it valid url. Secondly I think you should pass this part as query parameter. Apparently you can do something like
'/aaa/bbb/ccc/' + encodeURIComponent(part) + '/ddd/eee'
You can pass it as query parameter like
'/aaa/bbb/ccc/ddd/eee?part='+encodeURIComponent(part)

How can I submit a hash key in an URL parameter?

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.

POST data issues

I have an issue with submitting post data. I have a form which have a couple of text fields in, and when a button is pressed to submit the data, it is run through a custom from validation (JS), then I construct a query string like
title=test&content=some content
which is then submitted to the server. The problem I had is when I have '&' (eg &nbsp) entered into one of the inputs which then breaks up the query string. Eg:
title=test&content=some content &nbsp
How do I get around this?
Thanks in advance,
Harry.
Run encodeURIComponent over each key and value.
var title = "test";
var content = "some content &nbsp ";
var data = encodeURIComponent('title') + /* You don't actually need to encode this as it is a string that only contains safe characters, but you would if you weren't sure about the data */
'=' + encodeURIComponent(title) +
'&' + encodeURIComponent('content') +
'=' + encodeURIComponent(content);
Encode the string..when you want to encode a query string with special characters you need to use encoding. ampersand is encoded like this
title=test&content=some content %26
basically any character in a query string can be replaced by its ASCII Hex equivalent with a % as the prefix
Space = %20
A = %41
B = %42
C = %43
...
You need to encode your query to make it URL-safe. You can refer to the following links on how to do that in JS:
http://xkr.us/articles/javascript/encode-compare/
http://www.webtoolkit.info/javascript-url-decode-encode.html
You said:
...and when a button is pressed to submit the data, it is run through a custom from validation (JS), then I construct a query string...
In the section where you are building the query string you should also run the value of each input through encodeURIComponent() as David Dorward suggested.
As you do - be careful that you only assign the new value to your processed query string and NOT the form element value, otherwise your users will think their input was somehow corrupted and potentially freak out.
[EDIT]
I just re-read your question and realized something important: you're encoding an &nbsp ;character. This is probably a more complicated issue than other posters here have read into. If you want that character, and other &code; type characters to transfer over you'll need to realize that they are codes. Those characters &, n, b, s, p and ; are not themselves the same as " " which is a space character that does not break.
You'll have to add another step of encoding/decoding. You can place this step either before of after the data is sent (or "POSTed").
Before:
(Using this question's answers)
var data = formElement.value;
data = rhtmlspecialchars(data, 0);
Which is intended to replace your "special" characters like with " " so that they are then properly encoded by encodeURIComponent(data)
Or after:
(using standard PHP functions)
<?PHP
$your_field_name = htmlspecialchars_decode(urldecode($_POST['your_field_name']));
?>
This assumes that you escaped the & in your POST with %26
If you replaced it with some function other than encodeURIComponent() you'll have to find a different way to decode it in PHP.
This should solve your problem:
encodeURIComponent(name)+'='+encodeURIComponent(value)+'&'+encodeURIComponent(name2)+'='+encodeURIComponent(value2)
You need to escape each value (and name if you want to be on the safe side) before concatenating them when you're building your query.
The JavaScript global function encodeURIComponent() does the escaping.
The global function escape() (DOM) does this for you in a browser. Although people are saying it is not doing the escaping well for unicode chars. Anyway if you're only concerned about '&' then this would solve your problem.

Categories

Resources