Strip Base64-encoded URL parameters with Javascript - javascript

I'm decoding my URL parameters in .NET as explained in this article.
In some cases I need to get the URL parameters in Javascript. But the problem is that some parameter values end at a '='.
Example: ?itemID=Jj1TI9KmB74=&cat=1
Javascript function:
function getUrlVars() {
var vars = [], hash;
var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
for (var i = 0; i < hashes.length; i++) {
hash = hashes[i].split('=');
vars.push(hash[0]);
vars[hash[0]] = hash[1];
}
return vars;}
I know my problem is at the split-function in the for-loop but I don't know how to solve it.
I also used jsuri for this but the problem still exists.
Can I solve this in Javascript or do I need to reconsider my encryption-method?

Having an unencoded = in the URL is invalid. To do this right, you would have to additionally apply encodeURIComponent() on the base64 encoded data.
Whether the base64 encoding still makes sense then, is for you to decide.
Reference: RFC 3986: Reserved characters

Having = unencoded in the URI query is invalid. You should escape it. However, for completeness, if you really needed to do this, try this:
Extra note: if you escaped the = using URI encoding, on the server side (e.g. $_GET) it'll be automatically decoded. With JavaScript and location, however, you must decode it first (decodeURIComponent) to work with it.
Instead of doing:
hash = hashes[i].split('=');
where subsequent equals signs are split too, do this instead (a non-greedy match before the first equals symbol for the key name, the rest for the value):
match = hashes[i].match(/([^=]+?)=(.+)/);
key = match[1];
value = match[2];

I assume you can't control the process generating the =s? As Pekka said it's wrong.
However you could manually break the string at the first =, e.g.
var i = hashes[i].indexof('=');
if (i > 0)
{
var key = hashes[i].substring(0,i);
vars.push(key);
if ((i+1) < hashes[i].length)
{
vars[key] = hashes[i].substring(i+1);
}
}
else
{
// No value
vars.push(hashes[i]);
}

Related

Regex for url line [duplicate]

This should be very simple (when you know the answer). From this question
I want to give the posted solution a try. My question is:
How to get the parameter value of a given URL using JavaScript regular expressions?
I have:
http://www.youtube.com/watch?v=Ahg6qcgoay4
I need:
Ahg6qcgoay4
I tried:
http://www.youtube.com/watch\\?v=(w{11})
But: I suck...
You almost had it, just need to escape special regex chars:
regex = /http\:\/\/www\.youtube\.com\/watch\?v=([\w-]{11})/;
url = 'http://www.youtube.com/watch?v=Ahg6qcgoay4';
id = url.match(regex)[1]; // id = 'Ahg6qcgoay4'
Edit: Fix for regex by soupagain.
Why dont you take the string and split it
Example on the url
var url = "http://www.youtube.com/watch?p=DB852818BF378DAC&v=1q-k-uN73Gk"
you can do a split as
var params = url.split("?")[1].split("&");
You will get array of strings with params as name value pairs with "=" as the delimiter.
Not tested but this should work:
/\?v=([a-z0-9\-]+)\&?/i
v is a query parameter, technically you need to consider cases ala: http://www.youtube.com/watch?p=DB852818BF378DAC&v=1q-k-uN73Gk
In .NET I would recommend to use System.Web.HttpUtility.ParseQueryString
HttpUtility.ParseQueryString(url)["v"];
And you don't even need to check the key, as it will return null if the key is not in the collection.
I know the question is Old and already answered but this can also be a solution
\b[\w-]+$
and I checked these two URLs
http://www.youtube.com/watch?v=Ahg6qcgoay4
https://www.youtube.com/watch?v=22hUHCr-Tos
DEMO
I use seperate custom functions which gets all URL Parameters and URL parts .
For URL parameters, (which is the final part of an URI String, http://domain.tld/urlpart/?x=a&y=b
function getUrlVars() {
var vars = {};
var parts = window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(m,key,value) {
vars[key] = value;
});
return vars;
}
The above function will return an array consisting of url variables.
For URL Parts or functions, (which is http://domain.tld/urlpart/?x=a&y=b
I use a simple uri split,
function getUrlParams() {
var vars = {};
var parts = window.location.href.split('/' );
return parts;
}
You can even combine them both to be able to use with a single call in a page or in javascript.

How do I force browser not to convert 'comma' to 2C symbols using JS?

I'm changing current user's path through a function:
function setSomeValue(someValues) {
var query = '';
for (var i = 0; i < someValues.length; i++) {
query += someValues[i] + ',';
}
if ('URLSearchParams' in window) {
var searchParams = new URLSearchParams(window.location.search);
searchParams.set("paramName", query);
var newRelativePathQuery = window.location.pathname + '?' + searchParams.toString();
history.pushState(null, '', newRelativePathQuery);
}
}
As you can see, I'm adding to user's location new words and want new location to be like this:
www.site.com?paramName=value1,value2,
But browser converts my commas into %2C so I get this:
www.site.com?paramName=value1%2Cvalue2%2C
What should be done to make pushing commas to URL possible?
(copy & paste from several comments)
It might be due to URLSearchParams and its toString method implementation - but we can’t know, because you have not shown us what that actually is. If that is not deliberately encoding the comma, and the browser simply does it automatically - then there’s little you can do about that.
If newRelativePathQuery contains the encoded versions already, maybe they could be replaced back to normal commas. But if history.pushState does it, then “other ways” to create the URL itself won’t help you much.
Since a debug output showed that newRelativePathQuery contains the encoded commas already, you can try and replace them back to commas, and see if that “survives” being pushed to the history then.
It's a little hacky, but here's one solution. Let's say we want to use URL's searchParams.set() to set ids=1,2,3,4 in our query string.
If you just do url.searchParams.set("ids", "1,2,3,4"), the URL will have ids=1%2C2%2C3%2C4. To avoid that encoding, first set ids=LIST_OF_IDS_PLACEHOLDER, get the URL as a string, and then replace LIST_OF_IDS_PLACEHOLDER with 1,2,3,4, like this:
const myList = [1,2,3,4],
url = new URL(document.location.href); // or however you get your URL object
url.searchParams.set("ids", "LIST_OF_IDS_PLACEHOLDER");
const newUrlString = url.toString().replace("LIST_OF_IDS_PLACEHOLDER", ids.join(','));
console.log(newUrlString); // this will include: ids=1,2,3,4

Parsing email from query string

I'm trying to create a piece of JS that will parse the email address from a url query string. Once that's done, I want it to send the results to anaytics for use in whatever I need to use it in.
so basically abc.com?wemail=abc#abc.com
<script type="text/javascript">
/*Extracts email from query string using ?email=name#abc.com*/
function GetUrlValue(VarSearch) {
var SearchString = window.location.search.substring(1);
var VariableArray = SearchString.split('&');
for (var i = 0; i < VariableArray.length; i++) {
var KeyValuePair = VariableArray[i].split('=');
if (KeyValuePair[0] == VarSearch) {
return KeyValuePair[1];
}
}
The anayltics is receiving the data, but the # sign is being replaced by %40 and it isn't coding it the way I want.
I'm sure that is it simple, but what changes need to be made to ensure this works properly?
The %40 symbol you are getting is the encoded url symbol for the # symbol.
Refer to the link which refers to the usage of
decodeURIComponent() function in javascript
url decode function javascript
please check this link out
The # symbol is a originally used when the URL contains authentication info:
user:pass#myurl.com
So modern browsers will encode the # symbol in query string to %40. Use decodeURIComponent() to decode the value before sending to Segment.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent

Add a class to an object using javascript for specific querystring

I want to use javascript or jquery to add a class to an object based on the URL query string.
So if the url is example.com/?var=1 then I want to add a new class to the object
#mydiv
This would then be repeated for ?var=2, ?var=3 and so on.
Here is what I have tried. The hope for this is that it would add a different class to the object if the query string was either ?var=2 or?var=3
var queryString = window.location.search.substr(1);
switch (queryString) {
case "2": document.getElementById('mydiv').className = 'newclass2';
;
break;
case "3": document.getElementById('mydiv').className = 'newclass2';
;
break;
}
EDIT:
It almost works now....
Here is my current code:
<script>
var queryString = window.location.search.substr(1);
var variant = queryString.split('=')[1];
switch(variant) {
case "stnl2": document.getElementById('getexclusive-sb').className = 'stnlvar2';
;
break;
case "stnl3": document.getElementById('getexclusive-sb').className = 'stnlvar3';
;
break;
}
</script>
It works if the url is "/?v=stnl2"
However Google content adds more to the url such as "?v=stnl2&utm_expid=42387987-0.dmsadhasjkdjasgdjgas-Q.4"
Is there a way for me to ignore the & and all details after so my code still works?
var getUrlVars = function(){
var vars = [], hash;
var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
for(var i = 0; i < hashes.length; i++){
hash = hashes[i].split('=');
vars.push(hash[0]);
vars[hash[0]] = hash[1];
}
if(vars[0] == window.location.href){
vars =[];
}
return vars;
}
var params = getUrlVars();
switch (params['var']){
...
}
Your params will have all the parameters from your query string. just past the variable name as a string and you will get the value of that parameter.
The solution you tried has two issues.
First, you are getting the number of variant incorrectly. With your code, queryString will be like "var=2". So if you want only number, you should also split it by =:
var queryString = window.location.search.substr(1);
var variant = queryString.split('=')[1];
switch(variant) {
// ...
}
Note that this still actually doesn't check the name of your parameter, i.e. var=. If it is the only parameter, it would work. Otherwise, for proper handling of query string in JS you might want to look at this question
Second, look attentively into your switch. Both branches are actually identical, so they would do exactly the same regardless of queryString. Seems like you copy-pasted it unintentionally.
UPD:
As a said in my original answer, I just pointed you to some issues in your solution and how to fix them. It would not work if there is more than one parameter. Of course, you can just ignore all the string after &. But still there would be many cases in which it still won't work: what if your parameter is not the first?
I think it is not a good idea to make such assumptions, so we come to what I said previously: you might need proper, full-fledged parsing of parameters. The link that I mentioned provides A LOT of solutions for this particular task, you may choose any of them. Another option is to use some existing library which have such function provided. That question and some other SO questions pointed me to these two:
jquery.parsequery — a jQuery plugin for this only purpose, with which you can do variant = $.query(location).get("paramName"). Seems to be old and not updated.
jsurl — a library for making different things with URLs, in particular, you can do variant = (new Url).query.paramName with it.
NB: (replace paramName with your actual parameter name, v or var or whatever)
Of course there could be some other good libs for it, also try googling on your own.

How to encode a query string so that it is the value of another query string in javascript?

I have a javascript function which passes as a query string value another query string.
In other words, I want the query string to be:
http://www.somesite.com/?somequery=%3fkey%3dvalue1%2520%26%2520key2%3value3
However, if I redirect like this:
var url = 'http://www.somesite.com/?somequery=';
url += escape('?key=value1&key2=value2');
window.location = url;
it ends up as http://www.somesite.com?somequery=?key1=value1&key2=value2 in firefox and IE7 which means that I can't parse the query string correctly.
I also tried using encodeURIComponent which didn't work either.
Is there another function or a hack to force the redirect to keep the somequery value escaped??
encodeURIComponent will work. (You may or may not want the leading ‘?’, depending on what the script is expecting.)
var c= 'd e'
var query= '?a=b&c='+encodeURIComponent(c);
var uri= 'http://www.example.com/script?query='+encodeURIComponent(query);
window.location= uri;
Takes me to:
http://www.example.com/script?query=%3Fa%3Db%26c%3Dd%2520e
When you hover over that it may appear once-decoded in the browser's status bar, but you will end up in the right place.
escape/unescape() is the wrong thing for encoding query parameters, it gets Unicode characters and pluses wrong. There is almost never a case where escape() is what you really need.
Native escape method does that. but also you can create a custom encoder like:
function encodeUriSegment(val) {
return encodeUriQuery(val, true).
replace(/%26/gi, '&').
replace(/%3D/gi, '=').
replace(/%2B/gi, '+');
}
this will replace keys used in query strings. further more you can apply it to any other custom encodings by adding needed key-values pairs.
function downloadFile(){
var filePath = "C:/Users/HP/Desktop/Project Folder/DemoProject/";
var fileInfo = "Error_Issue Minor Cosmetic & Major Fatal Issues (Demo_Project) (2017)_GeneratedOn_12_21_2017 21924 AM.xlsx";
if((filePath != undefined && filePath.length > 0) && (fileName != undefined && fileName.length > 0)){
var downloadUrl = "../download?fileName="+encodeURIComponent(fileName)+"&filePath="+encodeURIComponent(filePath);
$window.location = downloadUrl;
}else{
alert("Please define a fileName for downloading...");
}
}
javascript:alert(escape('?key=value1&key2=value2'));
Works fine for me?

Categories