My issue is the following:
I have a field with a file path: "\\random.ad.test.stuff.com\folder\level 1\51. level 2\ level 3"
I want to create an array with this information
function myFunction() {
var str = "\\random.ad.test.stuff.com\folder\level 1\51. level 2\level 3";
var array = str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "_");
document.getElementById("demo").innerHTML = array;
}
Problem is that \51 the character code for a right parenthesis. So the result is
"_random_ad_test_stuff_comfolder_level 1__. level 2_level 3".
How can I escape the \51 as well as insert a _after .com ?
You can't escape the string after-the-fact. In a string literal, as you said, \51 is ), exactly as though you'd typed ) in the string literal; there is no difference in the resulting string:
console.log("\51" === ")"); // true
You have to escape the characters in the literal:
var str = "\\\\random.ad.test.stuff.com\\folder\\level 1\\51. level 2\\level 3";
// --------^-^-------------------------^-------^--------^------------^
console.log(str);
Note that this is just because you're using a string literal. If you read that string from somewhere, there's no need to escape it at all. Escaping (in this sense) is a string literal thing, not a string thing.
You've said this comes from an XML file, and asked what you have to do to the file to avoid this problem. The answer is: Nothing. Read in the XML file, and when you get those filenames from it, you'll get strings with the correct characters again, escaping is for string literals, but XML isn't a string literal.
Example:
// "Read" the file
var xmlText = document.querySelector("#xml").textContent;
// Parse it
var oParser = new DOMParser();
var oDOM = oParser.parseFromString(xmlText, "application/xml");
// Use its contents; the information you'll get will be valid strings,
// no escaping needed
var entries = oDOM.querySelectorAll("entry");
console.log(entries[0].getAttribute("attr"));
console.log(entries[1].firstChild.nodeValue);
<script id="xml" type="text/xml"><root>
<entry attr="\\random.ad.test.stuff.com\folder\level 1\51. level 2\level 3" />
<entry>\\random.ad.test.stuff.com\folder\level 1\51. level 2\level 3</entry>
</root></script>
In that example, I've shown taking the string from an attribute, or from the body of an element, the two usual ways you put information in XML.
I have a string
str = "{'a':1}";
JSON.parse(str);
VM514:1 Uncaught SyntaxError: Unexpected token '(…)
How can I parse the above string (str) into a JSON object ?
This seems like a simple parsing. It's not working though.
The JSON standard requires double quotes and will not accept single quotes, nor will the parser.
If you have a simple case with no escaped single quotes in your strings (which would normally be impossible, but this isn't JSON), you can simple str.replace(/'/g, '"') and you should end up with valid JSON.
I know it's an old post, but you can use JSON5 for this purpose.
<script src="json5.js"></script>
<script>JSON.stringify(JSON5.parse('{a:1}'))</script>
If you are sure your JSON is safely under your control (not user input) then you can simply evaluate the JSON. Eval accepts all quote types as well as unquoted property names.
var str = "{'a':1}";
var myObject = (0, eval)('(' + str + ')');
The extra parentheses are required due to how the eval parser works.
Eval is not evil when it is used on data you have control over.
For more on the difference between JSON.parse and eval() see JSON.parse vs. eval()
Using single quotes for keys are not allowed in JSON. You need to use double quotes.
For your use-case perhaps this would be the easiest solution:
str = '{"a":1}';
Source:
If a property requires quotes, double quotes must be used. All
property names must be surrounded by double quotes.
var str = "{'a':1}";
str = str.replace(/'/g, '"')
obj = JSON.parse(str);
console.log(obj);
This solved the problem for me.
Something like this:
var div = document.getElementById("result");
var str = "{'a':1}";
str = str.replace(/\'/g, '"');
var parsed = JSON.parse(str);
console.log(parsed);
div.innerText = parsed.a;
<div id="result"></div>
// regex uses look-forwards and look-behinds to select only single-quotes that should be selected
const regex = /('(?=(,\s*')))|('(?=:))|((?<=([:,]\s*))')|((?<={)')|('(?=}))/g;
str = str.replace(regex, '"');
str = JSON.parse(str);
The other answers simply do not work in enough cases. Such as the above cited case: "title": "Mama's Friend", it naively will convert the apostrophe unless you use regex. JSON5 will want the removal of single quotes, introducing a similar problem.
Warning: although I believe this is compatible with all situations that will reasonably come up, and works much more often than other answers, it can still break in theory.
sometimes you just get python data, it looks a little bit like json but it is not. If you know that it is pure python data, then you can eval these data with python and convert it to json like this:
echo "{'a':1}" | /usr/bin/python3 -c "import json;print(json.dumps(eval(input())))"
Output:
{"a": 1}
this is good json.
if you are in javascript, then you could use JSON.stringify like this:
data = {'id': 74,'parentId': null};
console.log(JSON.stringify(data));
Output:
> '{"id":74,"parentId":null}'
If you assume that the single-quoted values are going to be displayed, then instead of this:
str = str.replace(/\'/g, '"');
you can keep your display of the single-quote by using this:
str = str.replace(/\'/g, '\'\');
which is the HTML equivalent of the single quote.
json = ( new Function("return " + jsonString) )();
I have to send characters like ü to the server as unicode character but as an ASCII-safe string. So it must be \u00fc (6 characters) not the character itself. But after JSON.stringify it always gets ü regardless of what I've done with it.
If I use 2 backslashes like \\u00fc then I get 2 in the JSON string as well and that's not good either.
Important constraint: I can't modify the string after JSON.stringify, it's part of the framework without workaround and we don't want to fork the whole package.
Can this be done? If so, how?
If, for some reason, you want your JSON to be ASCII-safe, replace non-ascii characters after json encoding:
var obj = {"key":"füßchen", "some": [1,2,3]}
var json = JSON.stringify(obj)
json = json.replace(/[\u007F-\uFFFF]/g, function(chr) {
return "\\u" + ("0000" + chr.charCodeAt(0).toString(16)).substr(-4)
})
document.write(json);
document.write("<br>");
document.write(JSON.parse(json));
This should get you to where you want. I heavily based this on this question: Javascript, convert unicode string to Javascript escape?
var obj = {"key":"ü"};
var str1 = JSON.stringify(obj);
var str2 = "";
var chr = "";
for(var i = 0; i < str1.length; i++){
if (str1[i].match(/[^\x00-\x7F]/)){
chr = "\\u" + ("000" + str1[i].charCodeAt(0).toString(16)).substr(-4);
}else{
chr = str1[i];
}
str2 = str2 + chr;
}
console.log(str2)
I would recommend though that you look into #t.niese comment about parsing this server side.
Depending on the exact scenario, you can affect the behavior of JSON.stringify by providing a toJSON method as detailed here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#tojson_behavior
If an object has a toJSON method that is a function, then calling JSON.stringify on that will use the result of that method rather than the normal serialization. You could combine this with the approaches mentioned in other answers to get the result you want, even if a library doesn't naturally provide any hooks for customization.
(Of course, its possible that a third-party library is itself doing something that overrides this behavior.)
I have string with file path. I want to replace all single backslashes ("\") with double backslashes ("\\").
var replaceableString = "c:\asd\flkj\klsd\ffjkl";
var part = /#"\\"/g;
var filePath = replaceableString .replace(part, /#"\\"/);
console.log(filePath);
Console showed me it.
c:asdlkjklsdfjkl
I found something like this, unfortunately it didn't work.
Replacing \ with \\
Try:
var parts = replaceableString.split('\\');
var output = parts.join('\\\\');
Personally, as I am not so expert in reg exps, I tend to avoid them when dealing with non-alphanumeric characters, both due to readability and to avoid weird mistake.
var replaceableString = "c:\asd\flkj\klsd\ffjkl";
alert(replaceableString);
This will alert you c:asdlkjklsdfjkl because '\' is an escape character which will not be considered.
To have a backslash in your string , you should do something like this..
var replaceableString = "c:\\asd\\flkj\\klsd\\ffjkl";
alert(replaceableString);
This will alert you c:\asd\flkj\klsd\ffjkl
JS Fiddle
Learn about Escape sequences here
If you want your string to have '\' by default , you should escape it .. Use escape() function
var replaceableString = escape("c:\asd\flkj\klsd\ffjkl");
alert(replaceableString);
JS Fiddle
You have several problems in your code.
To get a \ in your string variable you need to escape it.
When you create a string like this: replaceableString = "c:\asd\flkj\klsd\ffjkl"; characters with a \ before are treated as escape sequences. So during the string creation, it tries to interpret the escape sequence \a, since this is not valid it stores the a to the string. E.g. \n would have been interpreted as newline.
I assume the # is coming from a .net example. Javascript does not know "raw" strings.
remove the quotes from your regex.
This would do what you want:
var string = "c:\\asd\\flkj\\klsd\\ffjkl";
var regex = /\\/g;
var FilePath = string.replace(regex, "\\\\");
Here is the answer:
For replacing single backslash with single forward slash:
var stringReplaced = String.raw`c:\asd\flkj\klsd\ffjkl`.split('\\').join('/')
console.log(stringReplaced);
For replacing double backslash with single forward slash:
var stringReplaced = String.raw`c:\\asd\\flkj\\klsd\\ffjkl`.split('\\\\').join('/')
console.log(stringReplaced);
\ is a escape character. Therefore replaceableString does not contain any backslashes.
To fix this you should declare the string like this:
var replaceableString = "c:\\asd\\flkj\\klsd\\ffjkl";
First encode the string
then replace all occurrences of %5C with %5C%5C
At the end decode the string
var result = encodeURI(input);
result=decodeURI(result.replace(/%5C/g,"%5C%5C"));
If you have no control over the contents of the string you are trying to find backslashes in, and it contains SINGLE \ values (eg. variable myPath contains C:\Some\Folder\file.jpg), then you can actually reference the single backslashes in JavaScript as String.fromCharCode(92).
So to get the file name in my filepath example above.
var justTheName = myPath.split(String.fromCharCode(92)).pop();
In case of string matching, it is better to use encodeURIComponent, decodeURIComponent.
match(encodeURIComponent(inputString));
function match(input)
{
for(i=0; i<arr.length; i++)
{
if(arr[i] == decodeURIComponent(input))
return true;
else return false;
}
}
In the case of a single back slash in the string, the javascript replace method did not allow me to replace the single back slash.
Instead I had to use the split method which returns an array of the split strings and then concatenate the strings without the back slash (or whatever you want to replace it with)
Solution (replaced backslash with underscore):
var splitText = stringWithBackslash.split('\\');
var updatedText = splitText[0] + '_' + splitText[1];
You need to pass to pass value of a string through String.raw before you assign value to a variable.
var replaceableString = String.raw`c:\asd\flkj\klsd\ffjkl`.replace(/\\/g,"\\\\");
console.log(replaceableString)
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¶m2=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