Simplest way to check if the current url contains a subdomain - javascript

I'm looking for the simplest way to check if the user is on the normal domain (domain.com) or is on a subdomain et.domain.com and display content based on that. If it matters I'm trying to do that on shopify.

You can split the url with dot(.) and check the length. This will only work for .com url.
Note: This will not work for domains like google.co.in
const domain = 'domain.com';
const subDomain = 'et.domain.com'
const isSubdomain = (domain) => domain.split('.').length > 2;
console.log(isSubdomain(domain));
console.log(isSubdomain(subDomain));

You can actually use regex method.
var isSubdomain = function(url) {
url = url || 'http://www.test-domain.com'; // just for the example
var regex = new RegExp(/^([a-z]+\:\/{2})?([\w-]+\.[\w-]+\.\w+)$/);
return !!url.match(regex); // make sure it returns boolean
}
console.log(isSubdomain("example.com"));
console.log(isSubdomain("http://example.com:4000"));
console.log(isSubdomain("www.example.com:4000"));
console.log(isSubdomain("https://www.example.com"));
console.log(isSubdomain("sub.example.com"));
console.log(isSubdomain("example.co.uk")); //it doesn't work on these very specific cases

Related

Fix URL in JavaScript

My web application has an input field where users can enter a link to their website. Usually they enter invalid URLs such as e-918kiss.com. I want to fix it to https://e-918kiss.com/ automatically.
But the URL can point to any domain name.
I tried using a tag to parse the URL, but it just appended it as the local path of the current source:
const elem = document.createElement('a');
a.href = 'Twitter.com/mhluska';
console.log(a.href); // "http://e-918kiss.com"
I researched some URL parsing libraries, but they usually just throw errors for invalid URLs. Includes native URL API.
Is there an easy way to try to create a valid link from any junk that the user might enter 918kiss ?
Regex is your friend. What is the best regular expression to check if a string is a valid URL?
At least minimum to know the TLD of the user domain. You can't try to guess TLD for random strings.
Then you should check if input value matches for a valid url, if not apply to the string the missing "https".
PS: domains are recommended to use SSL (https) as protocol reference but its not sure https is enabled on your users website.
Maybe this will help:
// https://stackoverflow.com/a/49849482/6525081
function isValidURL(string) {
var res = string.match(/(http(s)?:\/\/.)?(www\.)?[-a-zA-Z0-9#:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9#:%_\+.~#?&//=]*)/g);
return (res !== null)
};
document.querySelector('#URL').addEventListener('change', function() {
// trigger the change event so that:
const isUrl = isValidURL((this.value).toString()); // variable for input value
if (isUrl !== true) { // if this is not already url,
newVal = 'http://www.'+this.value+'.com'; // set it as url and
this.value = newVal; // add it as the input value
}
else {return false} // if not abort
});
</script>
<input type="text" id="URL" placeholder="type string..."/>

Javascript window.opener.postMessage Cross Origin with multiple sub domains

I'm trying to allow multiple subdomains when doing :
window.opener.postMessage(...);
This works but this is not safe as all possible domains are allowed and I don't want this :
window.opener.postMessage('MyMSG', '*');
This works for a single domain :
window.opener.postMessage('MyMSG', 'https://example.com');
But what if I want to allow this : *.example.com ?
Of course this:
window.opener.postMessage('MyMSG', '*.example.com');
window.opener.postMessage('MyMSG', 'https://*.example.com');
window.opener.postMessage('MyMSG', 'https://(.*)example.com');
does not works
What is the right way to do that? Is that even possible?
Thank you
The targetOrigin expects * or an exact uri, ie no subdomain wildcards.
If you want to post to multiple targets than you will need a separate postMessage() call for each. To make this easier you can just put all the domains into a list and iterate over the list instead of hard-coding each call.
var someData = {};
var subdomains = ["one","two","three"];
for(var subdomain of subdomains){
let target = "http://"+subdomain+".example.com"
window.postMessage(someData,target);
}
But this come with maintenance cost of keeping the list updated
Now depending on which end your code is at you can also use certain methods to get an exact uri at runtime. Note examples use URL to parse out just the protocol and host to get a proper value to pass to postMessage.
If you are on the end that opened a window, or the parent of iframe, you can just grab the src,href, or whatever property used to indicate the url for the window, iframe, etc.
//if using for instance window.open()
//you already know the url as it has to be passed to the function
var target = window.open("http://example.com/some/path");
//so in this case you would first save the url to a variable and use that variable for both
var url = new URL("http://example.com/some/path");
var targetDomain = url.protocol + "//" + url.host;
var target = window.open(url.href);
target.postMessage("message",targetDomain);
//if using an iframe just grab the src property and parse the domain from that
var url = new URL(iframeElement.src);
var targetDomain = url.protocol+"//"+url.host;
iframeElement.contentWindow.postMessage("message",targetDomain);
Now if you are on the other side, ie in the iframe or the opened window you can use document.referrer with the exception when opening a non-secure url from a secure page. Meaning document.referrer won't be set when you open a http:// url when your page is using https://
var url = new URL( document.referrer );
var target = url.protocol+"//"+url.host;
//opened window
window.opener.postMessage("message",target);
//iframe
window.parent.postMessage("message",target);

Javascript: Compare top-level domain [duplicate]

How i can get the domain name example.com from the set of possible subdomains sub1.example.com sub2.example.com sub3.example.com using javascript ...?
var parts = location.hostname.split('.');
var subdomain = parts.shift();
var upperleveldomain = parts.join('.');
To get only the second-level-domain, you might use
var parts = location.hostname.split('.');
var sndleveldomain = parts.slice(-2).join('.');
The accepted answer will work to get the second level domain. However, there is something called "public suffixes" that you may want to take into account. Otherwise, you may get unexpected and erroneous results.
For example, take the domain www.amazon.co.uk.
If you just try getting the second level domain, you'll end up with co.uk, which is probably not what you want. That's because co.uk is a "public suffix", which means it's essentially a top level domain. Here's the definition of a public suffix, taken from https://publicsuffix.org:
A "public suffix" is one under which Internet users can (or historically could) directly register names.
If this is a crucial part of your application, I would look into something like psl (https://github.com/lupomontero/psl) for domain parsing. It works in nodejs and the browser, and it's tested on Mozilla's maintained public suffix list.
Here's a quick example from their README:
var psl = require('psl');
// TLD with some 2-level rules.
psl.get('uk.com'); // null);
psl.get('example.uk.com'); // 'example.uk.com');
psl.get('b.example.uk.com'); // 'example.uk.com');
This is faster
const firstDotIndex = subDomain.indexOf('.');
const domain = subDomain.substring(firstDotIndex + 1);
The generic solution is explained here http://rossscrivener.co.uk/blog/javascript-get-domain-exclude-subdomain
From above link
var domain = (function(){
var i=0,domain=document.domain,p=domain.split('.'),s='_gd'+(new Date()).getTime();
while(i<(p.length-1) && document.cookie.indexOf(s+'='+s)==-1){
domain = p.slice(-1-(++i)).join('.');
document.cookie = s+"="+s+";domain="+domain+";";
}
document.cookie = s+"=;expires=Thu, 01 Jan 1970 00:00:01 GMT;domain="+domain+";";
return domain;
})();
function getDomain() {
const hostnameArray = window.location.hostname.split('.')
const numberOfSubdomains = hostnameArray.length - 2
return hostnameArray.length === 2 ? window.location.hostname : hostnameArray.slice(numberOfSubdomains).join('.')
}
console.log(getDomain());
This will remove all subdomains, so "a.b.c.d.test.com" will become "test.com"
If you want to verify if a specific subdomain exists
var parts = location.hostname.split('.');
if(parts.includes('subdomain_to_search_here')){
//yes
}else{
//no
}
some more robust version, which is independent of the subdomain count
function getDomain() {
const hostname = window.location.hostname.split('.');
hostname.reverse();
return `${hostname[1]}.${hostname[0]}`;
}

Will 'http:url' work for all browsers and devices?

In making a function that validates a user URL and prepends http: at the front, I have to take cases of www, https and // into account as being valid urls. The way I have it written now (see below), I only prepend http: , so that cases of //stackoverflow.com don't turn into http: ////stackoverflow.com.
This means that a url like stackoverflow.com becomes http:stackoverflow.com.
In Firefox and Chrome, this works just fine, but these URLS will be clicked from a variety of browsers and devices. Is it something that'll work universally? It'll be easy to rewrite this check for a // case, but I'm interested in the answer.
Prepend method:
function prependHTTPtoWebURL() {
var url = (el('org_website').value);
var httpVar;
var testFor;
if (url) {// If there's a website URL value
testFor = url.toLowerCase();
if (testFor.indexOf("http") != 0){
httpVar = 'http:'; //add it
url = httpVar + url;
el('org_website').value = url;
}
}
}
Try playing with regex. Check this code for instance:
var someurl = "www.google.com";
var otherurl = "google.com";
var anotherurl = "//google.com";
function prependHTTPtoWebURL(url) {
var newurl = url.replace(/^(http)?(:)?(\/\/)?/i,'');
return 'http://' + newurl;
}
console.log(prependHTTPtoWebURL(someurl));
console.log(prependHTTPtoWebURL(otherurl));
console.log(prependHTTPtoWebURL(anotherurl));
The ouput in console.log will be:
http://www.google.com
http://google.com
http://google.com
Since you are specifying a subdomain (www) on the first one, that is respected. It avoids ending with four diagonals, like http:////. If your url was something like :google.com, it would also fix it correctly.
You can see it live here: http://jsfiddle.net/zRBUj/
Edit: Adding the /i Kate mentioned.
Change http: to http://
See these links for more info:
Anatomy of a URL
How the web works

Get The Current Domain Name With Javascript (Not the path, etc.)

I plan on buying two domain names for the same site. Depending on which domain is used I plan on providing slightly different data on the page. Is there a way for me to detect the actual domain name that the page is loading from so that I know what to change my content to?
I've looked around for stuff like this but most of it doesn't work the way I want it to.
For instance when using
document.write(document.location)
on JSFiddle it returns
http://fiddle.jshell.net/_display/
i.e. the actual path or whatever that is.
How about:
window.location.hostname
The location object actually has a number of attributes referring to different parts of the URL
Let's suppose you have this url path:
http://localhost:4200/landing?query=1#2
So, you can serve yourself by the location values, as follow:
window.location.hash: "#2"
​
window.location.host: "localhost:4200"
​
window.location.hostname: "localhost"
​
window.location.href: "http://localhost:4200/landing?query=1#2"
​
window.location.origin: "http://localhost:4200"
​
window.location.pathname: "/landing"
​
window.location.port: "4200"
​
window.location.protocol: "http:"
window.location.search: "?query=1"
Now we can conclude you're looking for:
window.location.hostname
If you are not interested in the host name (for example www.beta.example.com) but in the domain name (for example example.com), this works for valid host names:
function getDomainName(hostName)
{
return hostName.substring(hostName.lastIndexOf(".", hostName.lastIndexOf(".") - 1) + 1);
}
function getDomain(url, subdomain) {
subdomain = subdomain || false;
url = url.replace(/(https?:\/\/)?(www.)?/i, '');
if (!subdomain) {
url = url.split('.');
url = url.slice(url.length - 2).join('.');
}
if (url.indexOf('/') !== -1) {
return url.split('/')[0];
}
return url;
}
Examples
getDomain('http://www.example.com'); // example.com
getDomain('www.example.com'); // example.com
getDomain('http://blog.example.com', true); // blog.example.com
getDomain(location.href); // ..
Previous version was getting full domain (including subdomain). Now it determines the right domain depending on preference. So that when a 2nd argument is provided as true it will include the subdomain, otherwise it returns only the 'main domain'
If you wish a full domain origin, you can use this:
document.location.origin
And if you wish to get only the domain, use can you just this:
document.location.hostname
But you have other options, take a look at the properties in:
document.location
You can get it from location object in Javascript easily:
For example URL of this page is:
http://www.stackoverflow.com/questions/11401897/get-the-current-domain-name-with-javascript-not-the-path-etc
Then we can get the exact domain with following properties of location object:
location.host = "www.stackoverflow.com"
location.protocol= "http:"
you can make the full domain with:
location.protocol + "//" + location.host
Which in this example returns http://www.stackoverflow.com
I addition of this we can get full URL and also the path with other properties of location object:
location.href= "http://www.stackoverflow.com/questions/11401897/get-the-current-domain-name-with-javascript-not-the-path-etc"
location.pathname= "questions/11401897/get-the-current-domain-name-with-javascript-not-the-path-etc"
window.location.hostname is a good start. But it includes sub-domains, which you probably want to remove. E.g. if the hostname is www.example.com, you probably want just the example.com bit.
There are, as ever, corner cases that make this fiddly, e.g. bbc.co.uk. The following regex works well for me:
let hostname = window.location.hostname;
// remove any subdomains, e.g. www.example.com -> example.com
let domain = hostname.match(/^(?:.*?\.)?([a-zA-Z0-9\-_]{3,}\.(?:\w{2,8}|\w{2,4}\.\w{2,4}))$/)[1];
console.log("domain: ", domain);
Since this question asks for domain name, not host name, a correct answer should be
window.location.hostname.split('.').slice(-2).join('.')
This works for host names like www.example.com too.
If you are only interested in the domain name and want to ignore the subdomain then you need to parse it out of host and hostname.
The following code does this:
var firstDot = window.location.hostname.indexOf('.');
var tld = ".net";
var isSubdomain = firstDot < window.location.hostname.indexOf(tld);
var domain;
if (isSubdomain) {
domain = window.location.hostname.substring(firstDot == -1 ? 0 : firstDot + 1);
}
else {
domain = window.location.hostname;
}
http://jsfiddle.net/5U366/4/
Use
document.write(document.location.hostname)​
window.location has a bunch of properties. See here for a list of them.
I figure it ought to be as simple as this:
url.split("/")[2]
If you want to get domain name in JavaScript, just use the following code:
var domain_name = document.location.hostname;
alert(domain_name);
If you need to web page URL path so you can access web URL path use this example:
var url = document.URL;
alert(url);
What about this function?
window.location.hostname.match(/\w*\.\w*$/gi)[0]
This will match only the domain name regardless if its a subdomain or a main domain
for my case the best match is window.location.origin
Combining a few answers from the above, the following works really well for me for destroying Cookies:
/**
* Utility method to obtain the domain URI:
*/
fetchDomainURI() {
if (window.location.port.length > 0) {
return window.location.hostname;
}
return `.${window.location.hostname.match(/\w*\.\w*$/gi)[0]}`;
}
Works for IP addresses with ports, e.g., 0.0.0.0:8000 etc, as well as complex domains like app.staging.example.com returning .example.com => allows for cross-domain Cookie setting and destroying.
I'm new to JavaScript, but cant you just use: document.domain ?
Example:
<p id="ourdomain"></p>
<script>
var domainstring = document.domain;
document.getElementById("ourdomain").innerHTML = (domainstring);
</script>
Output:
domain.com
or
www.domain.com
Depending on what you use on your website.
Even if the question is about the domain name, the accepted solution includes the subdomain (eg. you get blog.example.com calling location.hostname).
For future reference I suggest a one-liner to extract only the domain (eg. https://blog.example.com/index.html -> example.com) as Micheal.
location.hostname.split('.').filter(( _, i) => i < 2).join('.')
Beware! It can break when the TLD is composed of two parts (eg. .co.uk). If that's your case change 2 with 3 in the code above.
you can use this to do away with the port number.
var hostname = window.location.host;
var urlWithoutPort = `https://${hostname}`;
console.log(urlWithoutPort);
https://publicsuffix.org/list/
(https://github.com/publicsuffix/list/blob/master/public_suffix_list.dat)
is needed to correctly parse out all domains without suffixes, working with dots as in the answers above will never completely be correct. Feel free to run the above codes samples against the public suffixes dat file to realize this.
You can roll your own code based on this or use a package like https://www.npmjs.com/package/tldts
getDomainWithoutSuffix('google.com'); // returns `google`
getDomainWithoutSuffix('fr.google.com'); // returns `google`
getDomainWithoutSuffix('fr.google.google'); // returns `google`
getDomainWithoutSuffix('foo.google.co.uk'); // returns `google`
getDomainWithoutSuffix('t.co'); // returns `t`
getDomainWithoutSuffix('fr.t.co'); // returns `t`
getDomainWithoutSuffix('https://user:password#example.co.uk:8080/some/path?and&query#hash'); // returns `example`

Categories