I am having problems when trying to use a rails variable within javascript code.
For example, I might define a link_to_remote, with parameter
:complete => "alert('my_var');"
If my_var = "I'm testing.", then the javascript code will break due to the single quote closing the code prematurely. If I try using escape_javascript(my_var) so that the quote gets turned into \', it doesn't seem to fix the problem.
I've noticed that when you try alert('I\'m testing'); there's a problem, but if you do alert('I\\'m testing'), it works. Since escape_javascript only turns ' into \', rather than \\', does somebody have a suggestion for how to handle this?
Thanks!
Eric
when you try alert('I\'m testing'); there's a problem
Backslash is also an escape in Ruby strings! So the string literal:
"alert('I\'m testing');"
means the string:
alert('I'm testing');
the backslash is gone already before JavaScript gets a look at it. When you are writing a JavaScript string literal inside a Ruby string literal you need to escape the escape, \\, to get a real \ that will then, in JavaScript, escape the apostrophe.
escape_javascript correctly generates the backslash for JavaScript, if a backslash was included in its input. But again, if you're writing a string literal, you have to escape the backslash to get a real backslash:
escape_javascript("\b") -> this is a backspace character!
escape_javascript("\\b") -> this is backslash-then-letter-b;
escaped for JavaScript literal to double-backslash-then-b.
So, this is fine:
"'"+escape_javascript(myvar)+"'"
alternatively, you can use a JSON encoder to create the JavaScript string literal including the surrounding quotes.
Related
I have a program (written in Clojure) that injects some JS code into a JS function, then evaluates it via Nashorn. I have no control over the code passes (it may contain quotes, simple quotes...).
It looks like this :
;; Clojure
(eval-str (str "print(evaluateCode(\"" s " \"))"))
// equivalent code in pseudo-js just for those not reading Clojure fluently
evalJS("println(evaluateCode(" + arbitraryJS + "))")
The evaluateCode function is already loaded.
// already loaded in Nashorn
function evaluateCode(code) {
// do something with the code
//...
eval(code);
}
This works fine for simple programs, ex. if arbitraryJS = "var a=123; print(a); return a;".
But as soon as the program contains quotes, it breaks. ex. "var a = 123; print("a is now", a);"
Note : the actual code is there.
You need to escape the string. place a \ before every ".
If you need the \ itself use it double \\
Sorry, I am not allowed to comment yet... :/
I would suggest to escape the quotes and backslashes. I would go for single quotes as JS string delimiters, as in Clojure you are bound to use double quotes for delimiting strings:
;; Clojure
(eval-str (str "print(evaluateCode('"
(clojure.string/replace s #"(['\\\\])" "\\\\$1")
"'))"))
The find and replace patterns each have four backslashes. As in Clojure backslash is an escape character, they actually denote only two backslashes. In regular expressions backslash is also an escape character, so in the end they just denote one, literal backslash each. So this means "prefix any occurrence of backslash or quote with a backslash."
You shouldn't worry about comments and templates and such, as the escape characters only exist in Clojure (after the replace), but are resolved the moment the complete string is parsed by the Javascript engine. The evaluateCode function will never see the escape characters, but the plain value of s.
Example
;; Clojure
(def s "a = 'test'; // 'test' used here")
(eval-str (str "print(evaluateCode('"
(clojure.string/replace s #"(['\\\\])" "\\\\$1")
"'))"))
This will evaluate to:
(eval-str "print(evaluateCode('a = \\'test\\'; // \\'test\\' used here'))")
Note that the backslashes are doubled in the above representation, but that is because Clojure needs that. The actual string only has single occurrences of the backslashes. If instead of calling eval-str, you would call println with the same argument, you would get this output:
print(evaluateCode('a = \'test\'; // \'test\' used here'))
That is the string interpreted by the Javascript engine, and so it interprets the backslashes as escape characters, passing the clean string to evaluateCode.
So if evaluateCode looked like this:
function evaluateCode(code) {
alert(code);
}
It would produce this alert:
a = 'test'; // 'test' used here
So, the escaping backslashes are not there at all in Javascript. It will see the exact same value as the Clojure symbol s represents.
In the after end I used the Apache Commons Lang StringUtils since the other solutions did not work. See it here.
I have the following Javascript code to obtain the inner string from an RegExp:
Function.prototype.method = function (name,func){
this.prototype[name] = func;
return this;
};
RegExp.method('toRawString', function(){
return this.toString().replace(/^.(.*).$/,"$1");
});
The purpose of this, is to avoid in string double quoting. For example, if you have a Windows file path "C:\My Documents\My Folder\MyFile.file", you can use it like the following:
alert(/C:\My Documents\My Folder\MyFile.file/.toRawString());
However it is not working for ""C:\My Documents\My Folder\" since it causes syntax error. The only way to avoid it is to keep double quoting at the end of the string. Thus it will be written
alert(/C:\My Documents\My Folder\\/.toRawString());
The fact is any odd number of back slashes on the end of the string will be an error, so all ending back slashes must be double escaped. It will not be hard to use a multiple line small implementation, but are there any single RegExp solution?
NOTE
When using toRawString the RegExp object for this is usually NOT going to be used for any other purpose except for that method. I just want to use the syntax of RegExp to avoid double back slashes in source code. Unfortunately the ending double slashes cannot be easily avoid. I think another workaround is to force a space at the end but that is another question then.
UPDATE
I finally solved the "another question" and posted the code here.
OK, I get what you're trying to do! It's hacky : )
Try something like:
return this.toString().slice(1, -1).replace(/\\+$/, '\\')
Hope that helps.
If you want to include the double quotes in the string just wrap it with single quotes.
s = '"C:\\My Documents\\My Folder\\MyFile.file"'
console.log(s) // Output => "C:\My Documents\My Folder\MyFile.file"
This produces a syntax error:
/C:\My Documents\/
But that regular expression could be written correctly like this:
/C:\\My Documents\\/
Or like this:
new RegExp("C:\\\\My Documents\\\\")
I think your function is just fine and is returning a correct result. Regular expressions just can't end with an unpaired backslash. It's not that you're double escaping - you're just escaping the escape character.
This would produce an error too:
new RegExp("C:\\My Documents\\")
A regular expression like this, for instance, can't be written without a pair of backslashes:
/C:\\What/
Without the second backslash, \W would be interpreted as a special character escape sequence. So escaping the escape character isn't only necessary at the end. It's required anywhere it might be interpreted as the beginning of an escape sequences. For that reason, it might be a good rule of thumb to always use two backslashes to indicate a backslash literal in a regular expression.
I am aware with escaping special characters in HTML.
But, I am still asking this as I have come across a situation.
I have a JSP, in which I am not allowed put validation on input. Users are entering special characters to test.
Input string:
'##$%
When I am displaying from database, I am using
<%= StringEscapeUtils.escapeHtml(map[i].get("text").toString())%>
where "map" is an array of Hashmap. This works fine.
The problem comes when I need to pass this string to JavaScript using
<input type="Button"
onclick="onEdit('<%= StringEscapeUtils.escapeHtml(map[i].get("text").toString())%>',
'<%= strShortCut%>','<%= map[i].get("uid")%>')" value="Edit">
The string becomes ''##$%'.
How do I escape a single quote?
If you would be using Java, maybe you can do the below in Java.
import org.apache.commons.lang.StringEscapeUtils;
...
String result = StringEscapeUtils.escapeJavaScript(jsString);
Just prepend every single quote with a backslash. Like the following:
StringEscapeUtils.escapeHtml(map[i].get("text").toString()).replace("\'","\\'")
But your problem is not only in the single quote. There is also the double quote (") and the backslash itself (\).
Use the same technique as shown before. You can also use regular expressions, but I showed you the simplest way.
To check the escape characters, look at the URL http://docs.oracle.com/javase/tutorial/java/data/characters.html.
I have a UIWebView and I want to inject some HTML to the end of it after its been loaded.
NSString* javaScript = [NSString stringWithFormat:#"document.body.innerHTML += '%#'", arbitraryHTML];
[self.webView stringByEvaluatingJavaScriptFromString:javaScript];
The above code works, but only if arbitraryHTML is properly formated. E.g. the single quote ' is escaped as \'
I'd like to clean up HTML in genearl so that I can pass it to a javascript function.
What are other characters that I need to escape or strings that could cause problems?
Here's an example of some HTML that breaks the above code:
<span><a onmouseover=\\\"jQuery\\'# >Test</a></span>"
Can this be done in genearl? What else am I missing?
Thanks!
You need to make sure the JS engine does not throw up. So you need to escape single quotes and backslashes. This should do the trick:
arbitraryHTML = [[arbitraryHTML
stringByReplacingOccurrencesOfString:#"\\" withString:#"\\\\"]
stringByReplacingOccurrencesOfString:#"'" withString:#"\\'"]];
Note that you also need to escape backslashes inside Objective-C strings as seen above.
Turns out that its not enough to escape just the single quote character. I also needed to escape /n and /r to make this work with all HTML in general.
There may be some other character that I missed, if I find a case I'll post it.
I want to use JQ to print to a div on my page. The string I want to print with contains HTML including apostrophes and double apostrophes.
Is there a plugin or function to escape this so that the string doesnt break the js variable? There may be the case that I can't escape all of the apostrophes and double apostrophes in the incoming data using a backslash, so I'm looking for a function that can do it.
EG;
var replacement = 'This content has an apostrophe ' and a double apostrophe "';
$("#overwrite").text(replacement);
TIA
If you wanted to type out a string that is assigned to a variable like in your example above, then just escape it yourself.
For example, if I know my data will have apostrophes, then I wrap it in quotes (what you are calling double apostrophes) and use the HTML shortcut for quotes " or you can use a backslash to escape the quote \". Either way works. So your example above would become:
var replacement = "This content has an apostrophe ' and a double apostrophe "";
If the user is typing in the string or you are getting data from a feed, then it would be best to use the javascript replace function to make sure the quotes are escaped, like this:
var text = $("input").val().replace(/\"/g,""");
There is no need to escape incoming data, as it is already a string.
The only reason you need to escape apostrophes and double apostrophes in JavaScript source is due to the fact the JavaScript engine has to determine where the string starts and ends.
For instance, assuming you have a div#source containing the text "Hi there, what's up!", it is perfectly safe to do $("#overwrite").text($("#source").text()).