How can I extract a URL from url("http://www.example.com")? - javascript

I need to get the URL of an element's background image with jQuery:
var foo = $('#id').css('background-image');
This results in something like url("http://www.example.com/image.gif"). How can I get just the "http://www.example.com/image.gif" part from that? typeof foo says it's a string, but the url() part makes me think that JavaScript and/or jQuery has a special URL type and that I should be able to get the location with foo.toString(). That doesn't work though.

Note that different browser implementations may return the string in a different format. For instance, one browser may return double-quotes while another browser may return the value without quotes. This makes it awkward to parse, especially when you consider that quotes are valid as URL characters.
I would say the best approach is a good old check and slice():
var imageUrlString = $('#id').css('background-image'),
quote = imageUrlString.charAt(4),
result;
if (quote == "'" || quote == '"')
result = imageUrlString.slice(5, -2);
else
result = imageUrlString.slice(4, -1);
Assuming the browser returns a valid string, this wouldn't fail. Even if an empty string were returned (ie, there is no background image), the result is an empty string.

You might want to consider regular expressions in this case:
var urlStr = 'url("http://www.foo.com/")';
var url = urlStr.replace(/^url\(['"]?([^'"]*)['"]?\);?$/, '$1');
This particular regex allows you to use formats like url(http://foo.bar/) or url("http://foo.bar/"), with single quotes instead of double quotes, or possibly with a semicolon at the end.

You could split the string at each " and get the second element:
var foo = $('#id').css('background-image').split('"')[1];
Note: This doesn't work if your URL contains quotation marks.

If it's always the same, I'd just take the substring of the URL without the prefix.
For instance, if it's always:
url("<URL>")
url("<otherURL>")
It's always the 5th index of the string to the len - 2
Not the best by all means, but probably faster than a Regex if you're not worried about other string formats.

There is no special URL type - it's a string representing a CSS url value. You can get the URL back out with a regex:
var foo = ${'#id').css('background-image');
var url = foo.match(/url\(['"](.*)['"]\)/)[1];
(that regex isn't foolproof, but it should work against whatever jQuery returns)

Related

Is there a more succinct way to get the last number in my url?

So I currently pass two variables into the url for use on another page. I get the last variable (ie #12345) with location.hash. Then from the other part of the url (john%20jacob%202) all I need is the '2'. I've got it working but feel there must be a cleaner and succinct way to handle this. The (john%20jacob%202) will change all the time to have different string lengths.
url: http://localhost/index.html?john%20jacob%202?#12345
<script>
var hashUrl = location.hash.replace("?","");
// function here to use this data
var fullUrl = window.location.href;
var urlSplit = fullUrl.split('?');
var justName = urlSplit[1];
var nameSplit = justName.split('%20');
var justNumber = nameSplit[2];
// function here to use this data
</script>
A really quick one-liner could be something like:
let url = 'http://localhost/index.html?john%20jacob%202?#12345';
url.split('?')[1].split('').pop();
// returns '2'
How about something like
decodeURI(window.location.search).replace(/\D/g, '')
Since your window.location.search is URI encoded we start by decoding it. Then replace everything that is not a number with nothing. For your particular URL it will return 2
Edit for clarity:
Your example location http://localhost/index.html?john%20jacob%202?#12345 consists of several parts, but the interesting one here is the part after the ? and before the #.
In Javascript this interesting part, the query string (or search), is available through window.location.search. For your specific location window.location.search will return ?john%20jacob%202?.
The %20 is a URI encoded space. To decode (ie. remove) all the URI encodings I first run the search string through the decodeURI function. Then I replace everything that is not a number in that string with an empty string using a regular expression.
The regular expression /\D/ matches any character that is not a number, and the g is a modifier specifying that I want to match everything (not just stop after the first match), resulting in 2.
If you know you are always after a tag, you could replace everything up until the "#"
url.replace(/^.+#/, '');
Alternatively, this regex will match the last numbers in your URL:
url.match(/(?<=\D)\d+$/);
//(positive look behind for any non-digit) one more digits until the end of the string

How to read only part of a string in Javascript

I am pulling in a string from another web page. I want to read that string into a variable but only after a certain point. Eg:
#stringexample
var variable;
I want variable to equal stringexample but not contain the # how could I do this?
This is how I am using the variable at the moment.
$("#Outputajax").load("folder/"+ variable +".html");
This is the way that works but isn't a variable.
$("#Outputajax").load("folder/webpage.html");
If you just want to trim of the first character, then you can use substring...
var input = "#stringexample";
input = input.substring(1);
//input = "stringexample"
Here is a working example
var myVariable = stringExample.replace('#','');
Could just use variable.substr(1) to cut off the first character.
If you want to specifically remove the hash from the start (but do nothing if the hash isn't there), try variable.replace(/^#/,"")
I understand you want to get everything in the string AFTER the hashtag. The other solutions will leave anything ahead of the hashtag in as well. And substring does not work if the hashtag is not the first symbol.
variable= "#stringexample".split("#")[1];
This splits the string into an array of strings, with the parameter as the point where to split, without including the parameter itself. There will be an empty string as the first parameter, and everything after the hashtag is the second string.
var slicer = function(somestring){
var parsedString = somestring;
parsedString = parsedString.slice(1);
return parsedString
}
// run from yors function with some string
var someYouVar = slicer("#something")

Finding image url via using Regex

Any working Regex to find image url ?
Example :
var reg = /^url\(|url\(".*"\)|\)$/;
var string = 'url("http://domain.com/randompath/random4509324041123213.jpg")';
var string2 = 'url(http://domain.com/randompath/random4509324041123213.jpg)';
console.log(string.match(reg));
console.log(string2.match(reg));
I tied but fail with this reg
pattern will look like this, I just want image url between url(" ") or url( )
I just want to get output like http://domain.com/randompath/random4509324041123213.jpg
http://jsbin.com/ahewaq/1/edit
I'd simply use this expression:
/url.*\("?([^")]+)/
This returns an array, where the first index (0) contains the entire match, the second will be the url itself, like so:
'url("http://domain.com/randompath/random4509324041123213.jpg")'.match(/url.*\("?([^")]+)/)[1];
//returns "http://domain.com/randompath/random4509324041123213.jpg"
//or without the quotes, same return, same expression
'url(http://domain.com/randompath/random4509324041123213.jpg)'.match(/url.*\("?([^")]+)/)[1];
If there is a change that single and double quotes are used, you can simply replace all " by either '" or ['"], in this case:
/url.*\(["']?([^"')]+)/
Try this regexp:
var regex = /\burl\(\"?(.*?)\"?\)/;
var match = regex.exec(string);
console.log(match[1]);
The URL is captured in the first subgroup.
If the string will always be consistent, one option would be simply to remove the first 4 characters url(" and the last two "):
var string = 'url("http://domain.com/randompath/random4509324041123213.jpg")';
// Remove last two characters
string = string.substr(0, string.length - 2);
// Remove first five characters
string = string.substr(5, string.length);
Here's a working fiddle.
Benefit of this approach: You can edit it yourself, without asking StackOverflow to do it for you. RegEx is great, but if you don't know it, peppering your code with it makes for a frustrating refactor.

Javascript - cleaning a string with str.replace()

I have a URL that can be divided in 3 parts and I want the middle one.
The URL is like this
http://www.site.com/place?siteurl=http://www.thisIsWhatIwant.com/bla/bla/&XXX
XXX means that the URL continues and may have a lot of characters including %, parenthesis, other ampersands, equal signs, etc...
I want what is in bold. I other words, to get rid of everything that is before the equal sign on siteurl= (including the equal sign) and also get rid of everything that is after the first ampersand after that, including the ampersand... so, after cleaning the URL it would become just:
http://www.thisIsWhatIwant.com/bla/bla/
how do I do that with Javascript's str.replace()?
thanks in advance
Rather than remove the text you don't want, you can extract the text you do want using String.match():
var s = "http://www.site.com/place?siteurl=http://www.thisIsWhatIwant.com/bla/bla/&XXX";
var middle = s.match(/siteurl\=(.*?)\&/i)[1];
You don't want to use String.replace here, use String.split:
if(window.location.search.indexOf('siteurl') > -1) {
var siteurl = window.location.search.split('siteurl=')[1];
siteurl = siteurl.substring(0, siteurl.indexOf('&'));
//do something with siteurl...
} else {
//siteurl is not in the URL.
}

Encode URL in JavaScript

How do you safely encode a URL using JavaScript such that it can be put into a GET string?
var myUrl = "http://example.com/index.html?param=1&anotherParam=2";
var myOtherUrl = "http://example.com/index.html?url=" + myUrl;
I assume that you need to encode the myUrl variable on that second line?
Check out the built-in function encodeURIComponent(str) and encodeURI(str).
In your case, this should work:
var myOtherUrl =
"http://example.com/index.html?url=" + encodeURIComponent(myUrl);
You have three options:
escape() will not encode: #*/+
encodeURI() will not encode: ~!##$&*()=:/,;?+'
encodeURIComponent() will not encode: ~!*()'
But in your case, if you want to pass a URL into a GET parameter of other page, you should use escape or encodeURIComponent, but not encodeURI.
See Stack Overflow question Best practice: escape, or encodeURI / encodeURIComponent for further discussion.
Stick with encodeURIComponent(). The function encodeURI() does not bother to encode many characters that have semantic importance in URLs (e.g. "#", "?", and "&"). escape() is deprecated, and does not bother to encode "+" characters, which will be interpreted as encoded spaces on the server (and, as pointed out by others here, does not properly URL-encode non-ASCII characters).
There is a nice explanation of the difference between encodeURI() and encodeURIComponent() elsewhere. If you want to encode something so that it can safely be included as a component of a URI (e.g. as a query string parameter), you want to use encodeURIComponent().
The best answer is to use encodeURIComponent on values in the query string (and nowhere else).
However, I find that many APIs want to replace " " with "+" so I've had to use the following:
const value = encodeURIComponent(value).replace('%20','+');
const url = 'http://example.com?lang=en&key=' + value
escape is implemented differently in different browsers and encodeURI doesn't encode many characters (like # and even /) -- it's made to be used on a full URI/URL without breaking it – which isn't super helpful or secure.
And as #Jochem points out below, you may want to use encodeURIComponent() on a (each) folder name, but for whatever reason these APIs don't seem to want + in folder names so plain old encodeURIComponent works great.
Example:
const escapedValue = encodeURIComponent(value).replace('%20','+');
const escapedFolder = encodeURIComponent('My Folder'); // no replace
const url = `http://example.com/${escapedFolder}/?myKey=${escapedValue}`;
I would suggest to use the qs npm package:
qs.stringify({a:"1=2", b:"Test 1"}); // gets a=1%3D2&b=Test+1
It is easier to use with a JavaScript object and it gives you the proper URL encoding for all parameters.
If you are using jQuery, I would go for the $.param method. It URL encodes an object, mapping fields to values, which is easier to read than calling an escape method on each value.
$.param({a:"1=2", b:"Test 1"}) // Gets a=1%3D2&b=Test+1
Modern solution (2021)
Since the other answers were written, the URLSearchParams API has been introduced. It can be used like this:
const queryParams = { param1: 'value1', param2: 'value2' }
const queryString = new URLSearchParams(queryParams).toString()
// 'param1=value1&param2=value2'
It also encodes non-URL characters.
For your specific example, you would use it like this:
const myUrl = "http://example.com/index.html?param=1&anotherParam=2";
const myOtherUrl = new URL("http://example.com/index.html");
myOtherUrl.search = new URLSearchParams({url: myUrl});
console.log(myOtherUrl.toString());
This solution is also mentioned here and here.
encodeURIComponent() is the way to go.
var myOtherUrl = "http://example.com/index.html?url=" + encodeURIComponent(myUrl);
But you should keep in mind that there are small differences from PHP version urlencode() and as #CMS mentioned, it will not encode every character. Guys at http://phpjs.org/functions/urlencode/ made JavaScript equivalent to phpencode():
function urlencode(str) {
str = (str + '').toString();
// Tilde should be allowed unescaped in future versions of PHP (as reflected below), but if you want to reflect current
// PHP behavior, you would need to add ".replace(/~/g, '%7E');" to the following.
return encodeURIComponent(str)
.replace('!', '%21')
.replace('\'', '%27')
.replace('(', '%28')
.replace(')', '%29')
.replace('*', '%2A')
.replace('%20', '+');
}
I think now in 2022 to be really safe, you should always consider constructing your URLs using the URL() interface. It'll do most of the job for you. So coming to your code,
const baseURL = 'http://example.com/index.html';
const myUrl = new URL(baseURL);
myUrl.searchParams.append('param', '1');
myUrl.searchParams.append('anotherParam', '2');
const myOtherUrl = new URL(baseURL);
myOtherUrl.searchParams.append('url', myUrl.href);
console.log(myUrl.href);
// Outputs: http://example.com/index.html?param=1&anotherParam=2
console.log(myOtherUrl.href);
// Outputs: http://example.com/index.html?url=http%3A%2F%2Fexample.com%2Findex.html%3Fparam%3D1%26anotherParam%3D2
console.log(myOtherUrl.searchParams.get('url'));
// Outputs: http://example.com/index.html?param=1&anotherParam=2
Or...
const params = new URLSearchParams(myOtherUrl.search);
console.log(params.get('url'));
// Outputs: http://example.com/index.html?param=1&anotherParam=2
Something like this is assured not to fail.
To encode a URL, as has been said before, you have two functions:
encodeURI()
and
encodeURIComponent()
The reason both exist is that the first preserves the URL with the risk of leaving too many things unescaped, while the second encodes everything needed.
With the first, you could copy the newly escaped URL into address bar (for example) and it would work. However your unescaped '&'s would interfere with field delimiters, the '='s would interfere with field names and values, and the '+'s would look like spaces. But for simple data when you want to preserve the URL nature of what you are escaping, this works.
The second is everything you need to do to make sure nothing in your string interfers with a URL. It leaves various unimportant characters unescaped so that the URL remains as human readable as possible without interference. A URL encoded this way will no longer work as a URL without unescaping it.
So if you can take the time, you always want to use encodeURIComponent() -- before adding on name/value pairs encode both the name and the value using this function before adding it to the query string.
I'm having a tough time coming up with reasons to use the encodeURI() -- I'll leave that to the smarter people.
What is URL encoding:
A URL should be encoded when there are special characters located inside the URL. For example:
console.log(encodeURIComponent('?notEncoded=&+'));
We can observe in this example that all characters except the string notEncoded are encoded with % signs. URL encoding is also known as percentage encoding because it escapes all special characters with a %. Then after this % sign every special character has a unique code
Why do we need URL encoding:
Certain characters have a special value in a URL string. For example, the ? character denotes the beginning of a query string. In order to successfully locate a resource on the web, it is necessary to distinguish between when a character is meant as a part of string or part of the URL structure.
How can we achieve URL encoding in JavaScript:
JavaScript offers a bunch of built-in utility functions which we can use to easily encode URLs. These are two convenient options:
encodeURIComponent(): Takes a component of a URI as an argument and returns the encoded URI string.
encodeURI(): Takes a URI as an argument and returns the encoded URI string.
Example and caveats:
Be aware of not passing in the whole URL (including scheme, e.g., https://) into encodeURIComponent(). This can actually transform it into a not functional URL. For example:
// for a whole URI don't use encodeURIComponent it will transform
// the / characters and the URL won't fucntion properly
console.log(encodeURIComponent("http://www.random.com/specials&char.html"));
// instead use encodeURI for whole URL's
console.log(encodeURI("http://www.random.com/specials&char.html"));
We can observe f we put the whole URL in encodeURIComponent that the forward slashes (/) are also converted to special characters. This will cause the URL to not function properly anymore.
Therefore (as the name implies) use:
encodeURIComponent on a certain part of a URL which you want to encode.
encodeURI on a whole URL which you want to encode.
To prevent double encoding, it's a good idea to decode the URL before encoding (if you are dealing with user entered URLs for example, which might be already encoded).
Let’s say we have abc%20xyz 123 as input (one space is already encoded):
encodeURI("abc%20xyz 123") // Wrong: "abc%2520xyz%20123"
encodeURI(decodeURI("abc%20xyz 123")) // Correct: "abc%20xyz%20123"
A similar kind of thing I tried with normal JavaScript:
function fixedEncodeURIComponent(str){
return encodeURIComponent(str).replace(/[!'()]/g, escape).replace(/\*/g, "%2A");
}
You should not use encodeURIComponent() directly.
Take a look at RFC3986: Uniform Resource Identifier (URI): Generic Syntax
sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
/ "*" / "+" / "," / ";" / "="
The purpose of reserved characters is to provide a set of delimiting characters that are distinguishable from other data within a URI.
These reserved characters from the URI definition in RFC3986 ARE NOT escaped by encodeURIComponent().
MDN Web Docs: encodeURIComponent()
To be more stringent in adhering to RFC 3986 (which reserves !, ', (, ), and *), even though these characters have no formalized URI delimiting uses, the following can be safely used:
Use the MDN Web Docs function...
function fixedEncodeURIComponent(str) {
return encodeURIComponent(str).replace(/[!'()*]/g, function(c) {
return '%' + c.charCodeAt(0).toString(16);
});
}
Performance
Today (2020.06.12) I performed a speed test for chosen solutions on macOS v10.13.6 (High Sierra) on browsers Chrome 83.0, Safari 13.1, and Firefox 77.0. This results can be useful for massive URLs encoding.
Conclusions
encodeURI (B) seems to be fastest, but it is not recommended for URLs
escape (A) is a fast cross-browser solution
solution F recommended by MDN is medium fast
solution D is slowest
Details
For solutions
A
B
C
D
E
F
I perform two tests
for short URL - 50 characters - you can run it HERE
for long URL - 1M characters - you can run it HERE
function A(url) {
return escape(url);
}
function B(url) {
return encodeURI(url);
}
function C(url) {
return encodeURIComponent(url);
}
function D(url) {
return new URLSearchParams({url}).toString();
}
function E(url){
return encodeURIComponent(url).replace(/[!'()]/g, escape).replace(/\*/g, "%2A");
}
function F(url) {
return encodeURIComponent(url).replace(/[!'()*]/g, function(c) {
return '%' + c.charCodeAt(0).toString(16);
});
}
// ----------
// TEST
// ----------
var myUrl = "http://example.com/index.html?param=1&anotherParam=2";
[A,B,C,D,E,F]
.forEach(f=> console.log(`${f.name} ?url=${f(myUrl).replace(/^url=/,'')}`));
This snippet only presents code of chosen solutions
Example results for Chrome
Nothing worked for me. All I was seeing was the HTML of the login page, coming back to the client side with code 200. (302 at first but the same Ajax request loading login page inside another Ajax request, which was supposed to be a redirect rather than loading plain text of the login page).
In the login controller, I added this line:
Response.Headers["land"] = "login";
And in the global Ajax handler, I did this:
$(function () {
var $document = $(document);
$document.ajaxSuccess(function (e, response, request) {
var land = response.getResponseHeader('land');
var redrUrl = '/login?ReturnUrl=' + encodeURIComponent(window.location);
if(land) {
if (land.toString() === 'login') {
window.location = redrUrl;
}
}
});
});
Now I don't have any issue, and it works like a charm.
Here is a live demo of encodeURIComponent() and decodeURIComponent() JavaScript built-in functions:
<!DOCTYPE html>
<html>
<head>
<style>
textarea{
width: 30%;
height: 100px;
}
</style>
<script>
// Encode string to Base64
function encode()
{
var txt = document.getElementById("txt1").value;
var result = btoa(txt);
document.getElementById("txt2").value = result;
}
// Decode Base64 back to original string
function decode()
{
var txt = document.getElementById("txt3").value;
var result = atob(txt);
document.getElementById("txt4").value = result;
}
</script>
</head>
<body>
<div>
<textarea id="txt1">Some text to decode
</textarea>
</div>
<div>
<input type="button" id="btnencode" value="Encode" onClick="encode()"/>
</div>
<div>
<textarea id="txt2">
</textarea>
</div>
<br/>
<div>
<textarea id="txt3">U29tZSB0ZXh0IHRvIGRlY29kZQ==
</textarea>
</div>
<div>
<input type="button" id="btndecode" value="Decode" onClick="decode()"/>
</div>
<div>
<textarea id="txt4">
</textarea>
</div>
</body>
</html>
Encode URL String
var url = $(location).attr('href'); // Get the current URL
// Or
var url = 'folder/index.html?param=#23dd&noob=yes'; // Or specify one
var encodedUrl = encodeURIComponent(url);
console.log(encodedUrl);
// Outputs folder%2Findex.html%3Fparam%3D%2323dd%26noob%3Dyes
For more information, go to, jQuery Encode/Decode URL String.
Use fixedEncodeURIComponent function to strictly comply with RFC 3986:
function fixedEncodeURIComponent(str) {
return encodeURIComponent(str).replace(/[!'()*]/g, function(c) {
return '%' + c.charCodeAt(0).toString(16);
});
}
You can use ESAPI library and encode your URL using the below function. The function ensures that '/'s are not lost to encoding while the remainder of the text contents are encoded:
function encodeUrl(url)
{
String arr[] = url.split("/");
String encodedUrl = "";
for(int i = 0; i<arr.length; i++)
{
encodedUrl = encodedUrl + ESAPI.encoder().encodeForHTML(ESAPI.encoder().encodeForURL(arr[i]));
if(i<arr.length-1) encodedUrl = encodedUrl + "/";
}
return url;
}
Don't forget the /g flag to replace all encoded ' '
var myOtherUrl = "http://example.com/index.html?url=" + encodeURIComponent(myUrl).replace(/%20/g,'+');
I always use this to encode stuff for URLs. This is completely safe because it will encode every single character even if it doesn't have to be encoded.
function urlEncode(text) {
let encoded = '';
for (let char of text) {
encoded += '%' + char.charCodeAt(0).toString(16);
}
return encoded;
}
let name = `bbb`;
params = `name=${name}`;
var myOtherUrl = `http://example.com/index.html?url=${encodeURIComponent(params)}`;
console.log(myOtherUrl);
Use backtick now in ES6 to encode urls
try this - https://bbbootstrap.com/code/encode-url-javascript-26885283

Categories