Embedding JavaScript Strings from an Page
I’m looking at a piece of code that’s a custom control that embeds a bit of JavaScript into a page. Part of this JavaScript is generating some static string text directly into the page. I’ve been running this code for a while now as part of an application I’m working on with a customer.
But a couple of days ago I ran into a couple of problems with this control and as it turns out the problem is that the JavaScript strings embedded into the HTML stream aren’t properly encoded. The code used is something like this (grossly simplified):
string markup = “Some Text”; string script = @” embedHtml(“{0}”); function embedHtml(result) {{ alert(result) }}”; this.Page.ClientScript.RegisterStartupScript(typeof(Page), “embedHtml”, string.Format(script,markup), true);
The idea is that the code gets some text that comes from the server side and gets embedded into the page. The client script basically takes the embedded string and displays it when the page loads (the real thing embeds a bunch of HTML into the page in dynamic positions but same idea).
Can you spot the problem???
Actually this is all fine and dandy with the code above. It works fine.
But it starts becoming a problem if the text that you are embedding contains special characters. Say the string that you embed contains carriage returns, extended characters or maybe more pertinently – double quotes (which is what blew my code up originally not surprisingly since the embedded string contained HTML).
For example take this C# string assignment on the server:
string markup = “Hello \”Rick\”\r\nRock On”;
which when generated into the client side with the code above results in:
embedHtml(“Hello “Rick” Rock On”);
which clearly is going to cause a JavaScript error when the page loads.
The problem is that using
embedHtml(“{0}”);
or
embedHtml(‘{0}’);
is a string literal and it has to be embedded into the page properly or else code will blow up sporadically as certain characters are part of the strings embedded.
The fix for this is to encode the string to embed. The easiest way to use proper JavaScript string encoding is to use JSON encoding on the string and you can do that with the following code:
///
///
///So now we can change the code to:
string markup = wwWebUtils.EncodeJsString(“Hello \”Rick\”\r\nRock On”); string script = @” embedHtml({0}); function embedHtml(result) {{ alert(result) }}”; this.Page.ClientScript.RegisterStartupScript(typeof(Page), “embedHtml”, string.Format(script,markup), true);
And voila – that works correctly. The embedded string in the JavaScript now looks like this:
“Hello \”Rick\”\r\nRock On”
Note that the embedHtml({0}) code has removed the quotes around the format/replace parameter as EncodeJsString will create the string with quotes around it so there’s no ambiguity about which string delimiters to use. This can also reduce the complexity of code that requires nested string expressions.
This same logic applies if you use script expressions inside of a page:
alert( <%= wwWebUtils.EncodeJsString("My name is Sam\r\nRoll on") %> );
One place where I’ve actually used this a lot in the past is for client script localization. If you do something like this for example:
alert( <%= HttpContext.GetGlobalResourceObject("Resources","WarrantyDetail") %> );
you can run into the same encoding problems and this code should be changed to:
alert( <%= wwWebUtils.EncodeJsString(HttpContext.GetGlobalResourceObject("Resources","WarrantyDetail")) %> );
I know a lot of people truly disdain ‘legacy’ ASP classic script tags, but in some cases – localization especially – they are the easiest and most readable way to accomplish the task. Of course the same rules could be implied with a Label or Literal control and encoding the text explicitly in code.
I’ve run into this problem on a few occasions myself and I see it frequently in other people’s code. While it may not be all that common to embed string literals into JavaScript when you do need to do it it’s very important to encode the string.
It’s these little details that are easy to miss when working with JavaScript so I’d thought I pass this one along… Hope this helps somebody out.
Incoming search terms for the article:
Similar articles
- CodeResource – Javascript Messages
The WCF service is deployed on different machine. Im able to get the http://MyServer/MYService.svc/jsdebug file by giving And I’m able to invoke the service method using javascript. After invoking the MyMethod. I get this error in the javascript –> The server method ‘MyMethod’ ... - Page 4 – Xara Xone Workbook step-by
Lisa (USEXPAT) posted this question recently in the Xara X Conference: I’m trying to put together a Website. The background color is purple. When I make little clipart designs in Xara and then export them, there are little pieces of white around them. How do I get rid of that? Lisa’s question is one that ... - Cheri Hayes, Book
From the Publisher Addressing the anxiety children and their families face when discovering head lice, this colorfully illustrated rhyming book is intended for preschool and elementary children, but will also be helpful for school nurses, teachers, and parents. Through the endearing narrative of a young girl with head lice, the story teaches valuable treatment lessons ... - How to Remove PC Live Guard
Delete PC Live Guard Right Now! How Did I Get Infected With PC Live Guard? PC Live Guard and badware just like it commonly end up on your computer due to the following causes. You will need to uninstall PC Live Guard if you think you’re infected: Freeware or shareware: Many times freeware or ... - From aarp
Thu, May 20, 2010 8:49:06 AM Don’t let big bank lobbyists win … From: “Barry Jackson, AARP” … Add to Contacts To: texas_long_horn2005@yahoo.com var YAHOO = {‘Shortcuts’ : {}}; if (typeof YAHOO == “undefined”) { var YAHOO = {}; } YAHOO.Shortcuts = YAHOO.Shortcuts || {}; YAHOO.Shortcuts.hasSensitiveText = true; YAHOO.Shortcuts.sensitivityType = ["sensitive_news_terms"]; YAHOO.Shortcuts.doUlt = ...
I was wondering if this could be used to encode CDATA closing tags
and came up with the following code to extend your
functionality:-
As you say it wouldn’t be a common occurrence, I just noticed this
was possible as ways of escaping a string can sometimes point to
security vulnerabilities. But since JavaScript is client side I
can’t see any advantage gained by escaping a JavaScript string
value anyway.
This renders in 3.5 as:-
I’d be interested in hearing your comments. As you say, it is best
to avoid a million rules but if you didn’t add ] encoding in this
function then you’d have to add it somewhere else which would mean
a double function call every time you wish to JS encode something.
I await your reply with interest!
I removed the surrounding quotes from your method and replaced this
with:
The parameters were supplied from variables (in a loop) when
building up the html, and so could contain anything.
You need to encode it as \u0027 rather than \\\’ as that still
prematurely ends the event code.
Glad it works as advertised… :-}
Regardless, *you are indeed correct* and thank you for prompting me
to look closer at my own code. The error of my ways was not
changing the legacy code in place, but rather doctoring your code
to suit. I realise now that your code above works just swell and my
implemenatation of it was at fault. After many years of surrounding
strings in single quotes (apostrophes) for javascript I had left
them in place. No need. To illustrate, in a simplified version,
what I had was:
thx for sharing your code, and have a nice day
when I escape a text containing both quotes I get this which is
still not OK.
Response.Write(String.Format(“{0:#,###}”, 123456789));
Which will print 123,456,789
case ‘\”:
sb.Append(“\\\’”);
break;
This should stop JavaScript enclosed in a CDATA tag having the
CDATA closed by user input containing ]]>
Although the alert box displays as it should, this produces invalid
XHTML because the ]]> sequence in the embedHtml function call
closes the CDATA tag. The reason for my encoding of the ] character
was to avoid the ]]> appearing as a literal in the produced
code. This still decodes correctly in JavaScript as well as
producing valid XHTML:-
Without the encoding of the single quote, the bare quote will
prematurely end the onclick event.
I did have to add encoding of single quotes for my use – writing
out JavaScript events to be called when clicking on a link, such
as:
Because it would mean that your JSON size would bloat by 4x the
size of the original content.
I also agree that escaping single quotes is necessary. Especially
when the function is called EncodeJsString and not
EncodeJSONStringAndAddAnOuterDelimiter
Using the helper you have provided exactly as is, the *correct*
implementation, after a new start and a fresh coffee is, of
course:
I thank you again Rick, your implementation is correct. ‘Error
between computer and chair’, as they say.
I wouldn’t say its a bug in the browser as surely a CDATA tag
denotes that a section shouldn’t be parsed, therefore it shouldn’t
be looking for quotes either?
Why not use \\uXXX for characters 32 to 127 ??
So where is the ‘ a problem unencoded and does encoded really solve
that problem if there is one?
some ‘ text ” with both quotes
Suppose you have the following code:-
Anybody has a tip how to escape strings used in JS in events?
Hmmm… I thought that JavaScript always uses UTF-8 formatting for
strings, but then maybe that’s just because I always force
everything into UTF-8. Seems to be using anything but UTF-8 for
page encoding would be a bad idea especially since makes
that so easy from designer all the way through the Response
Encoding.
This will cause the HTML to render as:-