I have stumbled across this issue and hope I can get some inputs here on what could be the cause.
I have a URL with some GET parameters as follows:
www.test.com/test.jsp?serial=Id123:true;Id456:true;Id789:false;&session=1234567&userId=test
I then extract the parameter to make a REST call
const params = new URLSearchParams(window.location.search);
console.log(window.location.search);
console.log(params.get("serial"));
console.log(params.get("session"));
console.log(params.get("userId"));
const url = new URL("service/resources/query?", document.baseURI).href;
fetch(url + params.toString())
I'd say half of the time my REST call would fail due to session and userId parameters being cut off. Instead, I'm seeing this in my browser
www.test.com/test.jsp?serial=Id123:true
And my console print out would show
?serialNum=ZD0222:True
Id123:True
null
null
Any suggestions on why this happens and how I can write differently here?
Additional note - could the semicolon be the cause here? I noticed that url only show first value of the first parameter.
I think your window.location.search is not what you expect.
Looks good when I explicitly define the URL.
const url = new URL("http://www.test.com/test.jsp?serial=Id123:true;Id456:true;Id789:false;&session=1234567&userId=test");
const params = new URLSearchParams(url.search);
console.log(url.search);
console.log(params.get("serialNum"));
console.log(params.get("sessionId"));
console.log(params.get("userId"));
I would take another direction, maybe something like
const url = 'http://www.test.com/test.jsp?serial=Id123:true;Id456:true;Id789:false;&session=1234567&userId=test',
matches = url.match(/([&?](\w*)=([^?&]*))/g),
res = matches.reduce((acc, el)=> {
const sub = el.match(/[&?](.*)=(.*)/)
acc[sub[1]] = sub[2]
return acc
}, {})
console.log(res)
Please note: that function is not dealing with many edge cases, but maybe can inspire You to find an acceptable way to get what You need.
You cannot have colon ( : ) in your URL, its considered as an invalid character. You can use colon only in special cases like specifying port number or in 'http://', etc.
Related
I am just starting to learn location API(s), such as redirection URL in javascript and I can not understand the following three lines,
Can someone explain me?
let windowUrl = new URLSearchParams(window.location.search);
const queryString = window.location.href;
const firstParam = queryString.substring(queryString.lastIndexOf("?") + 1).split("=")[0];
The first line is useless. As you can see, windowUrl never gets used.
The following two lines:
window.location.href is nothing but the URL that you see in your browser's location bar. Say, https://www.youtube.com/watch?v=123456
so queryString = "https://www.youtube.com/watch?v=123456"
what the 2nd line does is to take everything that comes after "?" in that string. So v=123456
Then, it splits v=123456 by "=" as a separator. So, finally you get 123456.
Now, all of the above is quite barbaric, as you could obtain the value that "v" parameter this way:
let url = new URL(window.location.href);
let v = url.searchParams.get("v");
URL is an interface that will, shall we say "analyze" a URL and give you methods to parse it conveniently, such as the searchParams method, and more.
MDN https://developer.mozilla.org/en-US/docs/Web/API/URL
Description inline the code:
// for Example: https://stackoverflow.com/questions/69835761/js-url-location-can-someone-explain?search=hello
windowUrl = new URLSearchParams(window.location.search);
// URLSearchParams object that helps you to provide data to the query url
// window.location.search will return the current search query from your url
queryString = window.location.href;
// the current url: in this case: https://stackoverflow.com/questions/69835761/js-url-location-can-someone-explain?search=hello
firstParam = queryString.substring(queryString.lastIndexOf("?") + 1).split("=")[0]
// you filter or prase the value from the query string
But you can have it easier, like #resle already wrote.
// get the current url
const uri = new URL(window.location.href);
const quersValue = uri.searchParams.get("search");
// output : hello
let windowUrl = new URLSearchParams(window.location.search) ==> fetching URL params from the url. E.g website.com/?hello=1
const queryString = window.location.href; ===> getting the URL of your current page.
const firstParam = queryString.substring(queryString.lastIndexOf("?") + 1).split("=")[0]; ===> String manipulation to get the first param from the URL. Would open dev tool and play with it, to get the feeling.
E.g:
const x = "https://stackoverflow.com/questions/69835761/js-url-location-can-someone-explain/?hello=1"
const x = "https://stackoverflow.com/questions/69835761/js-url-location-can-someone-explain/?hello=1"
console.log(x)
Result: 'hello'
So here's a breakdown of what the code does:
let windowUrl = new URLSearchParams(window.location.search);
Here an instance of a URLSearchParams object which parses the search (effectively the query string).
const queryString = window.location.href;
This grabs the href (i.e. the entire URL including the query string and hash) and names it queryString (very bad name)
const firstParam = queryString.substring(queryString.lastIndexOf("?") + 1).split("=")[0];
This grabs the variable named "queryString" which is the href and finds the last index of ? which the code author hoped would designate the place where the query string starts (which is not correct). It then does some string manipulation to attempt get the first query string parameter key which would probably work for most cases but not all.
This code can be greatly simplified to:
const firstParam = (new URL(window.location.href)).searchParams.keys()?.[0];
This will use the JS URL class to parse the URL correctly and get the first key of the search parameters. ?.[0] is the optional chaining operator for arrays
Note that the 3rd line is wrong in this case because a URL like https://example.com/test?param=a&other=b¶m=c#hashwith?questionmark
is valid but the code will think the first URL parameter is questionmark instead of param which would be the expected answer.
I'm trying to replace string globally using the variable, but getting an unexpected replacement while replacing it. I've searched the same issue but didn't get any solutions so I'm posting it here. Maybe you guys will lead me where I'm doing a mistake.
Here is the case:
I have an HTML mail body and a list of links that I've extracted from the mail body and stored it as an array.
I'm trying to iterate the links array and try to find the match from the mail body.
And when I'm using the replace() method to replace the link by adding some prefix.
Looks pretty straight forward, right?
Here is the issue I'm getting while replacing the links.
There are some repeated links I've. While trying to replace them with the prefix, it is getting replace 2 times.
for e.x.
prefix = 'http://this.prefix?redirect_uri='
link = 'http://google.com'
// Expected Output
http://this.prefix?redirect_uri=http://google.com
// Getting Output
http://this.prefix?redirect_uri=http://this.prefix?redirect_uri=http://google.com
You can see the prefix is getting repeated.
I'm sharing my actual code, So, it will be more helpful to you guys to understand what I mean to say.
let mailBody = `
<div dir="auto">
aabc.pagerduty.com
[FIRING:1] TooManyContainerRestarts (http 10.0.95.123:8080 kube-state-metrics newton newton/prometheus-operator-prometheus prometheus-operator-kube-state-metrics infra critical) </p>
View Incident
<p>URGENCY </p>
</div>
`;
const links = [
'https://aabc.pagerduty.com/incidents',
'https://aabc.pagerduty.com/incidents/P9X3024'
]
const processTrackingLinks = (linkArray, mailBody) => {
const prefix = 'https://test.io?redirect_uri=';
// const mapping = [];
for (let i=0; i < linkArray.length; i++){
const replacer = new RegExp(linkArray[i], 'g')
mailBody = mailBody.replace(replacer, prefix + linkArray[i]);
}
return mailBody;
};
mailBody = processTrackingLinks(links, mailBody);
console.log(mailBody);
If you have any idea why it is happening,
Am I doing something wrong or it is an issue
just let me know.
Any resolution will be appreciated. :)
How about this approach. You don't need the links array anymore.
const process = mailBody => {
return mailBody.replace(/href="/g, `href="http://test.io?redirect_uri=`)
}
The problem lies in the links array you are using. Double replacement is due to the fact that "https://abc.pagerduty.com/incidents" is a substring of "https://abc.pagerduty.com/incidents/".
Use the following array instead:
let links = [
'https://abc.pagerduty.com/incidentsgoogle',
'https://abc.pagerduty.com/incidents/',
'https://abc.facebook.com'
];
As seen already, this approach would fail for strings with substring present in the links array.
To avoid such issues, change the process function to:
const process = (links, mailBody) => {
let prefix = 'http://test.io?redirect_uri='
return mailBody.replace(/( href=["'])/g, "$1" + prefix);
};
So, I'm working on a bookmarklet that takes the website url, which contains the actual text '%2F' in it, and split it there. However, because %2F represents a forward slash, it keeps splitting where there are forward slashes and not at %2F. How can I fix this?
Current Code:
javascript:(
function(){
var str = window.location.href;
var res = str.split("%2F");
alert(res); //Just here to test the output
}
)
();
Example Input:
http://blocked.com-default.ws/?oI=14697520135&type=chromium-m&url=i.imgur.com%2F4uHAdNPg.jpg
Example Output:
http:,,blocked.com-default.ws/?oI=14697520135&type=chromium-m&url=i.imgur.com%2F4uHAdNPg.jpg
Wanted Output:
http://blocked.com-default.ws/?oI=14697520135&type=chromium-m&url=i.imgur.com ,4uHAdNPg.jpg
It looks like you want you focus your splitting more to a specific portion of the location rather that the whole URL. In your case, it looks like you really want to split the value of the url variable which is found in window.location.search. You can probably accomplish close what you want if you just use that instead of window.location.href.
A better approach might be to target the actual value of the url variable.If you don't need to support IE, an easy way to get that data is to use UrlSearchParams:
const params = new URLSearchParams(window.location.search);
const url = params.get("url");
const res = url.split('%2F');
If you do need more cross browser reach, you can also do this with a simple regular expression:
const url = window.location.search.match(/url=[^&]+/)
const res = url.split('%2F');
The split works as expected:
const str = 'http://blocked.com-default.ws/?oI=14697520135&type=chromium-m&url=i.imgur.com%2F4uHAdNPg.jpg';
console.log(str.split('%2F'));
But window.location.href doesn't always return exactly the same string that is being displayed in the address bar, or encode stuff without you knowing about it. It is quite browser-dependent. For example, on chrome, you might observe this:
location.href = 'http://example.com/ xxx';
console.log(location.href); // http://example.com/%20xxx
In any case, it just looks like you're trying to manipulate your URL by hand. Don't do that. By using new URL(...), location.searchParams, decodeURIComponent, and other native APIs to easily manipulate URLs, you'll probably achieve what you're looking for in an easier and safer way ;)
This is in Chrome at least. If my window's URL is https://www.google.com/search?q=JavaScript+URLSearchParams and I run this in the JavaScript console:
url = new URL(document.URL);
urlsp = url.searchParams;
console.log(urlsp.get("q"));
then what gets logged to the console is not JavaScript+URLSearchParams, but JavaScript URLSearchParams. This is a pain because the userscript that I am trying to write needs access to the actual value of the q parameter; and + are not treated the same by the browser. Sure, I could write some code that would process the URL as a string, but that would be tedious and error-prone. The same deal happens with the value %3A in a parameter, but it gets returned as : instead. How do I get URLSearchParams to return the actual value of a URL's parameter?
URLSearchParams is a representation of the parsed search params. Parsing (specified here) includes decoding the values.
If you don't want to parse the search params, but instead just e.g. split on ampersands and = signs, then don't use url.searchParams. Use instead url.search, and perform the splitting yourself.
I could write some code that would process the URL as a string, but
that would be tedious and error-prone
I don't know about that, this is a fairly new API and we've been surviving ok without for a long time. There are problems with it anyway, last I checked the API doesn't support parameter arrays like foo[]=1&foo[]=2. It really isn't very complicated and it's not that much code to just roll your own:
class UrlParams {
constructor(search) {
this.qs = (search || location.search).substr(1);
this.params = {};
this.parseQuerstring();
}
parseQuerstring() {
this.qs.split('&').reduce((a, b) => {
let [key, val] = b.split('=');
a[key] = decodeURIComponent(val).replaceAll('+', ' ');
return a;
}, this.params);
}
get(key) {
return this.params[key];
}
}
const params = new UrlParams('?q=Javascript+Stuff');
console.log(params.get('q'));
url = new URL(document.URL);
urlsp = url.searchParams;
console.log(encodeURI(urlsp.get("q")));
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURI
I have an application that shows photos and albums to a user. Based on current state of the application I show appropriate view. Everytime view changes I change the url, controller then gets the url value using window.location.hash
It returns the string of this form:
"photos/byalbum/albumid"
"photos/allphotos"
"photos/eachphoto/albumid/photoid"
My question is how do I parse this using javscript regular expressions to determine which view I should be showing and also to get the parameters (albumId/photoId)
I think you are better off doing this, then regex:
"photos/eachphoto/albumid/photoid".split("/")
Then you get array that you can examine.
Rather than using regex, you should probably simply split the string on "/" and examine each piece of the value for the data that you need.
var urlString = <your returned value here>;
var urlPieces = urlString.split("/");
var view = urlPieces[1];
var album = (urlPieces[2]) ? urlPieces[2] : "";
var photo = (urlPieces[3]) ? urlPieces[3] : "";
Then play with your data as you wish. :)
If someone is still interesting in this question I used this lib: path-to-regexp to solve that problem.
basically you can convert an url into variables using a pattern.
For example:
const pattern = 'photos/eachphoto/:albumid/:photoid'
const path = 'photos/eachphoto/10/23'
const converter = pathToRegex.match(pattern, { decode: decodeURIComponent })
const params = converter(path)?.params || {}
and params will be similar to: { albumid: "10", photoid: "23" }