So I have the following bit of code which works to some extent.
var url = window.location.protocol + "//" + window.location.host + window.location.pathname;
var sanitized = url
.replace(/^https\:\/\//, '') // remove the leading http:// (temporarily)
.replace(/\/+/g, '/') // replace consecutive slashes with a single slash
.replace(/\/+$/, ''); // remove trailing slashes
url = 'https://' + sanitized;
window.onload = function urlChange(){
location.replace(url);
}
The only issue is that once the url gets changed the page keeps reloading as if I have an infinite loop going on.
Any ideas?
Thanks!
You need to check if the url is actually changed, and only replace their location if it has been changed. You should also probably use window.url rather than manually constructing it from the protocol, host and pathname.
var sanitized = window.url
.replace(/^https\:\/\//, '') // remove the leading http:// (temporarily)
.replace(/\/+/g, '/') // replace consecutive slashes with a single slash
.replace(/\/+$/, ''); // remove trailing slashes
sanitized = 'https://' + sanitized; // add https to the front
window.onload = function urlChange() {
if (window.url !== sanitized) {
location.replace(sanitized);
}
}
To update the url without actually updating the location (which results in reloading the browser), you may use the html5 pushState event:
var url = window.location.protocol + "//" + window.location.host + window.location.pathname;
var sanitized = url
.replace(/^https\:\/\//, '') // remove the leading http:// (temporarily)
.replace(/\/+/g, '/') // replace consecutive slashes with a single slash
.replace(/\/+$/, ''); // remove trailing slashes
url = 'https://' + sanitized;
window.onload = function urlChange(){
window.history.pushState("object or string", "Title", url);
}
You could remove the "/" from the url only if exist at the end using endsWith() in the string.
You could check if the "/" exist at the end of hash or pathname and remove it
then redirect to wanted page without the "/" at end.
Also you need to skip homepage as it will always be "/" on the pathname
var url_view = window.location.href;
var url_path = window.location.pathname;
var url_hash = window.location.hash;
if(url_path.endsWith("/") || url_hash.endsWith("/")) {
//Skip Home Page
if(url_path !== "/"){
url_view = url_view.slice(0,-1);
window.location.replace(url_view);
}
}
Related
How can I effectively add a "path" to the middle of an URL in JavaScript?
I want to add embed to an URL, so the URL https://blog.com/post/123 will end up looking like this https://blog.com/embed/post/123?
Cheers
You can create an <a> and set the href property. Then prepend embed to the pathname and use toString() to get the whole URL.
let element = document.createElement('a');
element.href = 'https://blog.com/post/123';
element.pathname = 'embed' + element.pathname;
console.log(element.toString());
You can do this, if the path is just a string
var path = "https://blog.com/post/123";
var withEmbed = path.replace(/\/post\//,'/embed/post/');
console.log(withEmbed);
You can use the location API.
https://developer.mozilla.org/en-US/docs/Web/API/Location
function addEmbed(location) {
return location.protocol + '//' + location.host +
'/embed' + location.pathname;
}
var url = document.createElement('a');
url.href = 'https://blog.com/post/123';
var embed = addEmbed(url);
console.log(embed); // "https://blog.com/embed/post/123"
Example: https://codepen.io/anon/pen/wXxvaq
The way i would do it, is to pass by ref/value the original URL and the text you wan to add, into a function. It then removes the "https://" (if necessary), splits the url at the first "/" and saves each part as a var. Finally it puts it all back together and outputs it to a on the html page.
This doesnt have to be outputted in this way, it could be saved as a global variable and then used in a link (but i didn't know what your plan was so i outputted it) :)
function addToURL(URL, add) {
URL = URL.replace(/(^\w+:|^)\/\//, '');
var part1 = URL.substring(0, URL.indexOf("/") + 1);
var part2 = URL.substring(URL.indexOf("/"), URL.length);
var result = "https://" + part1 + add + part2;
document.getElementById("demo").innerHTML = result;
}
Here's the example I made: https://codepen.io/anon/pen/RJBwZp
Hope this helps :P
http://www.google.com/site!#656126.72367
In this url, how to split and remove the part from exclamatory mark when page loaded using JS.
I just want http://www.google.com/site
Use string replace method , match every character after ! with regular expression and replace with ""
var url = 'http://www.google.com/site!#656126.72367';
url = url.replace(/!.*/,"");
You could use:
var host = window.location.hostname; // will be www.google.com
var path = window.location.pathname; // will be /site
In the end, you will have:
var url = "http://" + host + path;
Note: you can also use window.location.protocol, which in this case is http::
var url = window.location.protocol + '//' + host + path;
Update: as suggested by Rajesh, the window.location object also has access to the hash:
var hash = window.location.hash; // will be 656126.72367
It might be useful to do a console.log(window.location) and see what's in there!
This method works even if the hash contains several ! or #
var url = 'http://www.google.com/site!#656126.72367';
url = url.substring(0, url.indexOf('!'));
document.write(url);
substring extracts the characters from a string, between two specified indices (in this case on the first occurence and then on !), and returns the new sub string.
jsFiddle demo
var url = "http://www.google.com/site!#656126.72367";
url = url.split('!')[0];
console.log(url);
I use the following javascript with regex to test url string.
var url = window.location.pathname;
// create regexp to match current url pathname and remove trailing slash if
// present as it could collide with the link in navigation in case
// trailing slash wasn't present there
urlRegExp = new RegExp(url == '/' ? window.location.origin + '/?$' : url.replace(/\/$/, ''));
// now grab every link from the navigation
$('.page-sidebar a').each(function () {
// and test its normalized href against the url pathname regexp
if (urlRegExp.test(this.href.replace(/\/$/, ''))) {
$(this).closest("li").addClass("active");
}
});
But this regex doesnt include the querystring. How can I do that?
Perhaps you could match a string with something like this and construct from it what you want.
var rx = new RegExp("^(?:([^:\\/?#]+):)?(?:\\/\\/((?:(([^:#]*)(?::([^:#]*))?)?#)?([^:\\/?#]*)(?::(\\d*))?))?((((?:[^?#\\/]*\\/)*)([^?#]*))(?:\\?([^#]*))?(?:#(.*))?)");
var url = "http://stackoverflow.com/questions/16053753/regex-for-url-with-querystring?a0b&c=d&e=f#anchor";
var val = url.match(rx);
val.forEach(function (part) {
var result = $("#result");
var $text = $("<p>").text(part);
result.append($text);
});
You can play with this code on jsfiddle
I'm making a small web app in which a user enters a server URL from which it pulls a load of data with an AJAX request.
Since the user has to enter the URL manually, people generally forget the trailing slash, even though it's required (as some data is appended to the url entered). I need a way to check if the slash is present, and if not, add it.
This seems like a problem that jQuery would have a one-liner for, does anyone know how to do this or should I write a JS function for it?
var lastChar = url.substr(-1); // Selects the last character
if (lastChar != '/') { // If the last character is not a slash
url = url + '/'; // Append a slash to it.
}
The temporary variable name can be omitted, and directly embedded in the assertion:
if (url.substr(-1) != '/') url += '/';
Since the goal is changing the url with a one-liner, the following solution can also be used:
url = url.replace(/\/?$/, '/');
If the trailing slash exists, it is replaced with /.
If the trailing slash does not exist, a / is appended to the end (to be exact: The trailing anchor is replaced with /).
url += url.endsWith("/") ? "" : "/"
I added to the regex solution to accommodate query strings:
http://jsfiddle.net/hRheW/8/
url.replace(/\/?(\?|#|$)/, '/$1')
This works as well:
url = url.replace(/\/$|$/, '/');
Example:
let urlWithoutSlash = 'https://www.example.com/path';
urlWithoutSlash = urlWithoutSlash.replace(/\/$|$/, '/');
console.log(urlWithoutSlash);
let urlWithSlash = 'https://www.example.com/path/';
urlWithSlash = urlWithSlash.replace(/\/$|$/, '/');
console.log(urlWithSlash);
Output:
https://www.example.com/path/
https://www.example.com/path/
It replaces either the trailing slash or no trailing slash with a trailing slash. So if the slash is present, it replaces it with one (essentially leaving it there); if one is not present, it adds the trailing slash.
You can do something like:
var url = 'http://stackoverflow.com';
if (!url.match(/\/$/)) {
url += '/';
}
Here's the proof: http://jsfiddle.net/matthewbj/FyLnH/
The URL class is pretty awesome - it helps us change the path and takes care of query parameters and fragment identifiers
function addTrailingSlash(u) {
const url = new URL(u);
url.pathname += url.pathname.endsWith("/") ? "" : "/";
return url.toString();
}
addTrailingSlash('http://example.com/slug?page=2');
// result: "http://example.com/slug/?page=2"
You can read more about URL on MDN
Before finding this question and it's answers I created my own approach. I post it here as I don't see something similar.
function addSlashToUrl() {
//If there is no trailing shash after the path in the url add it
if (window.location.pathname.endsWith('/') === false) {
var url = window.location.protocol + '//' +
window.location.host +
window.location.pathname + '/' +
window.location.search;
window.history.replaceState(null, document.title, url);
}
}
Not every URL can be completed with slash at the end. There are at least several conditions that do not allow one:
String after last existing slash is something like index.html.
There are parameters: /page?foo=1&bar=2.
There is link to fragment: /page#tomato.
I have written a function for adding slash if none of the above cases are present. There are also two additional functions for checking the possibility of adding slash and for breaking URL into parts. Last one is not mine, I've given a link to the original one.
const SLASH = '/';
function appendSlashToUrlIfIsPossible(url) {
var resultingUrl = url;
var slashAppendingPossible = slashAppendingIsPossible(url);
if (slashAppendingPossible) {
resultingUrl += SLASH;
}
return resultingUrl;
}
function slashAppendingIsPossible(url) {
// Slash is possible to add to the end of url in following cases:
// - There is no slash standing as last symbol of URL.
// - There is no file extension (or there is no dot inside part called file name).
// - There are no parameters (even empty ones — single ? at the end of URL).
// - There is no link to a fragment (even empty one — single # mark at the end of URL).
var slashAppendingPossible = false;
var parsedUrl = parseUrl(url);
// Checking for slash absence.
var path = parsedUrl.path;
var lastCharacterInPath = path.substr(-1);
var noSlashInPathEnd = lastCharacterInPath !== SLASH;
// Check for extension absence.
const FILE_EXTENSION_REGEXP = /\.[^.]*$/;
var noFileExtension = !FILE_EXTENSION_REGEXP.test(parsedUrl.file);
// Check for parameters absence.
var noParameters = parsedUrl.query.length === 0;
// Check for link to fragment absence.
var noLinkToFragment = parsedUrl.hash.length === 0;
// All checks above cannot guarantee that there is no '?' or '#' symbol at the end of URL.
// It is required to be checked manually.
var NO_SLASH_HASH_OR_QUESTION_MARK_AT_STRING_END_REGEXP = /[^\/#?]$/;
var noStopCharactersAtTheEndOfRelativePath = NO_SLASH_HASH_OR_QUESTION_MARK_AT_STRING_END_REGEXP.test(parsedUrl.relative);
slashAppendingPossible = noSlashInPathEnd && noFileExtension && noParameters && noLinkToFragment && noStopCharactersAtTheEndOfRelativePath;
return slashAppendingPossible;
}
// parseUrl function is based on following one:
// http://james.padolsey.com/javascript/parsing-urls-with-the-dom/.
function parseUrl(url) {
var a = document.createElement('a');
a.href = url;
const DEFAULT_STRING = '';
var getParametersAndValues = function (a) {
var parametersAndValues = {};
const QUESTION_MARK_IN_STRING_START_REGEXP = /^\?/;
const PARAMETERS_DELIMITER = '&';
const PARAMETER_VALUE_DELIMITER = '=';
var parametersAndValuesStrings = a.search.replace(QUESTION_MARK_IN_STRING_START_REGEXP, DEFAULT_STRING).split(PARAMETERS_DELIMITER);
var parametersAmount = parametersAndValuesStrings.length;
for (let index = 0; index < parametersAmount; index++) {
if (!parametersAndValuesStrings[index]) {
continue;
}
let parameterAndValue = parametersAndValuesStrings[index].split(PARAMETER_VALUE_DELIMITER);
let parameter = parameterAndValue[0];
let value = parameterAndValue[1];
parametersAndValues[parameter] = value;
}
return parametersAndValues;
};
const PROTOCOL_DELIMITER = ':';
const SYMBOLS_AFTER_LAST_SLASH_AT_STRING_END_REGEXP = /\/([^\/?#]+)$/i;
// Stub for the case when regexp match method returns null.
const REGEXP_MATCH_STUB = [null, DEFAULT_STRING];
const URL_FRAGMENT_MARK = '#';
const NOT_SLASH_AT_STRING_START_REGEXP = /^([^\/])/;
// Replace methods uses '$1' to place first capturing group.
// In NOT_SLASH_AT_STRING_START_REGEXP regular expression that is the first
// symbol in case something else, but not '/' has taken first position.
const ORIGINAL_STRING_PREPENDED_BY_SLASH = '/$1';
const URL_RELATIVE_PART_REGEXP = /tps?:\/\/[^\/]+(.+)/;
const SLASH_AT_STRING_START_REGEXP = /^\//;
const PATH_SEGMENTS_DELIMITER = '/';
return {
source: url,
protocol: a.protocol.replace(PROTOCOL_DELIMITER, DEFAULT_STRING),
host: a.hostname,
port: a.port,
query: a.search,
parameters: getParametersAndValues(a),
file: (a.pathname.match(SYMBOLS_AFTER_LAST_SLASH_AT_STRING_END_REGEXP) || REGEXP_MATCH_STUB)[1],
hash: a.hash.replace(URL_FRAGMENT_MARK, DEFAULT_STRING),
path: a.pathname.replace(NOT_SLASH_AT_STRING_START_REGEXP, ORIGINAL_STRING_PREPENDED_BY_SLASH),
relative: (a.href.match(URL_RELATIVE_PART_REGEXP) || REGEXP_MATCH_STUB)[1],
segments: a.pathname.replace(SLASH_AT_STRING_START_REGEXP, DEFAULT_STRING).split(PATH_SEGMENTS_DELIMITER)
};
}
There might also be several cases when adding slash is not possible. If you know some, please comment my answer.
For those who use different inputs: like http://example.com or http://example.com/eee. It should not add a trailling slash in the second case.
There is the serialization option using .href which will add trailing slash only after the domain (host).
In NodeJs,
You would use the url module like this:
const url = require ('url');
let jojo = url.parse('http://google.com')
console.log(jojo);
In pure JS, you would use
var url = document.getElementsByTagName('a')[0];
var myURL = "http://stackoverflow.com";
console.log(myURL.href);
I have an input field that saves a URL, I'd like this saved input to recognize when "Http//" is absent from the start of the variable but have no idea where to begin... is it possible to check only a portion of a string? - then have a function that will append if necessary?
If you also want to allow "https://", I would use a regular expression like this:
if (!/^https?:\/\//i.test(url)) {
url = 'http://' + url;
}
If you're not familiar with regular expressions, here's what each part means.
^ - Only match at the beginning of the string
http - Match the literal string "http"
s? - Optionally match an "s"
: - Match a colon
\/\/ - Escape the "/" characters since they mark the beginning/end of the regular expression
The "i" after the regular expression makes it case-insensitive so it will match "HTTP://", etc.
A simple solution for what you want is the following:
var prefix = 'http://';
if (s.substr(0, prefix.length) !== prefix)
{
s = prefix + s;
}
However there are a few things you should be aware of...
The test here is case-sensitive. This means that if the string is initially Http://example.com this will change it to http://Http://example.com which is probably not what you want. You probably should also not modify any string starting with foo:// otherwise you could end up with something like http://https://example.com.
On the other hand if you receive an input such as example.com?redirect=http://othersite.com then you probably do want to prepend http:// so just searching for :// might not be good enough for a general solution.
Alternative approaches
Using a regular expression:
if (!s.match(/^[a-zA-Z]+:\/\//))
{
s = 'http://' + s;
}
Using a URI parsing library such as JS-URI.
if (new URI(s).scheme === null)
{
s = 'http://' + s;
}
Related questions
Javascript equalsIgnoreCase: case insensitive string comparation
javascript startswith
How do I parse a URL into hostname and path in javascript?
Lifted from the Linkenizer (Null won't mind)
link = (link.indexOf('://') === -1) ? 'http://' + link : link;
This will prepend 'http://' to link if it can't find the :// indicating protocol. This won't work well if :// occurs elsewhere in the string, but it's good enough.
Examples:
http://www.google.com -> http://www.google.com
ftp://google.com -> ftp://google.com
www.google.com -> http://www.google.com
google.com -> http://google.com
Since you said you are saving this URL, it would be a better idea to do this on the server-side, so clients who have js disabled won't mess up the links.
ES6, one liner
Here is a "modern" approach:
const withHttp = url => !/^https?:\/\//i.test(url) ? `http://${url}` : url;
You can now use withHttp as a function:
const myUrl = withHttp("www.example.org");
ES6, one liner
const withHttp = (url) => url.replace(/^(?:(.*:)?\/\/)?(.*)/i, (match, schemma, nonSchemmaUrl) => schemma ? match : `http://${nonSchemmaUrl}`);
Tested for (all return http://www.google.com):
www.google.com
google.com
//google.com
http://www.google.com
https://www.google.com
ftp://www.google.com
If anyone need to know how it works add a comment and I'll add an explanation.
Here is what I use for instant gratification. utilizing the keyup listener in jquery.
$('#url').keyup(function () {
if ( ($(this).val().length >=5) && ($(this).val().substr(0, 5) != 'http:') && ($(this).val().substr(0, 5) != 'https') ) {
$(this).val('http://' + $(this).val());
}
});
Below code snippet checks for:
Checks if url is not blank
Removes stray blank spaces at start or end
Checks for http://example.com, https://example.com AND //example.com
if (!!url && !!url.trim()) { //Check if url is not blank
url = url.trim(); //Removes blank spaces from start and end
if (!/^(https?:)?\/\//i.test(url)) { //Checks for if url doesn't match either of: http://example.com, https://example.com AND //example.com
url = 'http://' + url; //Prepend http:// to the URL
}
} else {
//Handle empty url
}
I altered #Mark Byers's answer to include "https://" as well.
function formatUrl(url){
var httpString = 'http://'
, httpsString = 'https://'
;
if (url.substr(0, httpString.length) !== httpString && url.substr(0, httpsString.length) !== httpsString)
url = httpString + url;
return url;
}
Something like this (writing by memory)?
if (url.toUpper(url.substring(0, 7) != "HTTP://")
url = "http://" + url;
if (url.indexOf('http://') != 0)
url = 'http://' + url;
You can avoid regexes (and consequently another problem) by using new URL():
function newURL(string) {
let url;
try {
url = new URL(string);
if (!url.hostname) {
// cases where the hostname was not identified
// ex: user:password#www.example.com, example.com:8000
url = new URL("https://" + string);
}
} catch (error) {
url = new URL("https://" + string);
}
return url;
}
const url = newURL('google.com');
console.log(url); // "https://google.com/"
It works for any string, see the package https://www.npmjs.com/package/new-url
I altered #Morgan Taylor's and #Mark Byer's answers to be case unsensitive. Works with http:// and https://
function formatUrl(url)
{
var httpString = "http://";
var httpsString = "https://";
if (url.substr(0, httpString.length).toLowerCase() !== httpString && url.substr(0, httpsString.length).toLowerCase() !== httpsString)
url = httpString + url;
return url;
}
You can use "StartsWith" a member of System.String.
if (url.ToUpper().StartsWith("HTTP://"))
{
}