Escaping apostrophe in jQuery - javascript

I'm trying to escape out of some apostrophe's in my JSON. I know it's not ideal but i append the data to the DOM and call it later in the code. At the moment i get an error whenever there is an ' in the data. I've tried using replace and encodeURI but just doesnt seem to work.
My code basically looks like:
var addItem = function (item, target){
var obj = $(item).data('obj');
var obj_string = JSON.stringify(obj);
target.append("<div data-obj='" + obj_string + "'> Added </div>
}
When i inspect the element it breaks when it gets to the apostrophe:
{"publisher":"EA","games":[{"game":"Dragon's"}]}
Looks like this in the element inspector:
{"publisher":"EA","games":[{"game":"Dragon" s"}]}
And everything that follows is broken. Any ideas how i escape it?
I've found lots of ways if it was pureply jquery but with it being in the html it seems to not work.

You can avoid the escaping and stringification© using .data() to set the obj to the element directly.
$('<div/>').data('obj', obj).text('Added').appendTo(target);
Just keep in mind with this method you won't get a data attribute on the actual element itself but the data will be there when you request it with .data.

You are concatenating your content with a string that already uses single quotes. The concatenated result will most likely be <div data-obj='Dragon's'> which is not what you want.
Either escape the single quote when concatenating it (not sure the entity won't be interpreted):
.append("<div data-obj='" + obj_string.replace("'", "‚") + "'> Added </div>");
Or safer, you can build your nodes with jQuery which will give you a native escaping for some performance penalty:
.append($("<div>Added</div>").data("obj", obj_string));

Rather than leaving yourself open to XSS, try:
var div = document.createElement('div');
div.appendChild(document.createTextNode("Added"));
div.setAttribute("data-obj",obj_string);
target.append(div);

Related

JSON.parse and JSON.stringify error on special character in string

console.log(JSON.stringify($('.btn').attr('data-obj')))
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="btn btn-info user_action" data-action="edit_faqs" data-obj="{SysID:2,Artist:Json Mras,Song:I'm yours}" data-toggle="modal " data-target="#SongsModal
"><i class="fa fa-edit "></i> Edit</button>
I found this but this is a little different in my case.
When I tried using JSON.stringify on the data I can see in the dev tools
//I want I'm Yours
"{\"Song\":\"I"
The data is stored in my database and I get it in ajax request and I want to use JSON.stringify to it because I will put it as a data-* on a button which will then be used when I click the button. On button click I want to use JSON.parse so I can iterate over it.
How to escape all special characters in JSON.stringify and JSON.parse
Error is:
Uncaught SyntaxError: Unexpected end of JSON input
That points to the JSON.stringify
Added a snippet but it didnt recreate problem so I added an image
Database:
Update:
I get the data from ajax request. After getting the data I use data_array = JSON.stringify(data[i]); then apply the data as data-obj='" + data_array + "'
That's not a problem with JSON, it's a problem with your misuse of HTML.
You inserted a raw string into a HTML attribute, probably from a template, possibly by doing something like
<button data-obj="<?php echo json_encode($data); ?>">
Or possibly in JavaScript
container.innerHTML = '<button data-obj="' + JSON.stringify(data) + '">';
so your quotes end up clashing with HTML's. You need to change your quotes into HTML entities; the minimum is changing double quotes " into " if you are using double quotes around the HTML attribute (the most common scenario).
You have not told us how you insert the content into the HTML, so I can't tell you how to do it until you do clarify.
EDIT: Apparently you are building HTML in JavaScript by concatenation. In that case, the solution I showed would work:
container.innerHTML = '<button data-obj="' + data_array.replace(/"/g, '"') + '">';
Or, if you're using single quotes to enclose the attribute (not commonly done, but certainly an option), you would need to change those to &apos; instead:
container.innerHTML = "<button data-obj='" + data_array.replace(/'/g, '&apos;') + "'>";
However, given that it's JavaScript we're talking about, and it can work with DOM, and DOM knows what's what... there's many other solutions. The most primitive one is to work with DOM directly:
let button = document.createElement('button');
button.setAttribute('data-obj', data_array);
container.appendChild(button);
When you do this, JavaScript manipulates the DOM directly, not HTML, so escaping is not needed.
A level above this would be to use a library like jQuery:
$('<button>').data('obj', data_array).appendTo('#container');
A level yet above that would be to use a library that employs data binding, like Angular, React, Vue, Ractive... where you would just set the value on your model, and the document automagically reflects that change.
Changing manually " into " is only needed if you directly manipulate HTML.

Javascript JSON.parse string onclick in-line

I'm using jquery to append HTML to an ID; specifically, I am having trouble placing a JSON-formatted string into the onclick parameter of an element. I intentionally want the JSON to be parsed onClick and am perfectly okay with the JSON living in the DOM for this specific effort.
I think the problem is related to escaping the quotes properly (because a Chrome Inspect Elements debug reveals that each JSON element is being treated as an HTML tag as opposed to a string--see https://ibb.co/eHOgq8 for screenshot of how the DOM is being interpreted)
var str = '{"artist":"So and So","title":"Not Relevant"}';
$("#d").append('<ul><li><a onclick="JSON.parse(\'' + str + '\')" title="NA">Link</a></li></ul>')
I've tried using numerous escaping mechanism and quote types as well as some native Javascript escaping and gotten no where. After 2 hours, I have to turn SO for help. Thank you so much in advance.
Try this :
var str = '{"artist":"So and So","title":"Not Relevant"}';
var jsonObj = JSON.parse(str);
$("#d").append('<ul><li><a onclick="alert(JSON.stringify(jsonObj))" title="NA">Link</a></li></ul>');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="d"></div>
Don't try to assign handlers with inline attributes - that's as bad as eval, and as you're experiencing, can lead to confusing issues with escape characters. Instead, attach handlers properly using Javascript instead, for example:
var str = '{"artist":"So and So","title":"Not Relevant"}';
$('#div').append('<ul><li><a title="etc">link</a></li></ul>');
$('div a').on('click', () => console.log(JSON.parse(str)));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="div"></div>

Adding JavaScript Function with arguments to an element from code behind

Hi Guys I've been dealing with an estrange thing while trying to pass string parameters to a JavaScript function from code behind, this is what I have actually in code behind which is wrong:
thumbnail = "<a href = 'javascript:RemovePirctureDetail(" + field1 + ",'" + tempname + "');' class='label label-default' rel='tooltip'>Remove</a>";
So this is the bad result I'm getting in the browser:
Remove
Meas that for some reason when I try to pass the string parameter, the html comes out bad formatted. The result should looks like this:
Remove
I tried already send the quotation marks like this /' from code behind, it did not work neither. How can I achieve this?
Thanks.
string thumbnail = "Remove";`
You need to use \ to escape the quotes inside, not /..
With javascript attribute I wouldn't use single quote, because it could be messy
Try to change in this way:
thumbnail = "Remove";
PS: Actually, I would NEVER use single quotes with attributes, it will cause an HTML validation error, HTML is not well formed with single quotes for attributes (although with inspection tools you see double quotes.. because inspection tools have the need to work with a well formed HTML, so if you want to see the real HTML of your page, view the source code (generally the option is on right-click on the page)

Is there a direct way of appending text to a DOM element with jQuery?

Is there a more direct way of writing the following in jQuery?
var $b = $('b');
$b.text($b.text() + ', World!!');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js">
</script>
<b>Hello</b>
This seams like something jQuery would have existing functionality for, as vanilla JavaScript can do it by direct access to the property.
document.querySelector('b').innerText += ', World!!';
I looked into the .append() method, however it appears that it isn't designed for appending text, even though it works:
$('b').append(', World!!');
Also the Additional Notes section warns of XSS vulnerabilities when using .append(), as it can potentially execute code.
No. As you have already pointed out, the cleanest way is by modifying the property directly.
To do that in jQuery you can get the DOM element reference from within the object:
var $b = $('b');
$b[0].innerText += ', World!!';
JSFiddle
Or,
You could pass a function to .text(), which isn't any 'cleaner' but can be very helpful if you want to use the context:
var $b = $('b');
$b.text(function(_,v){
return v += ', World!!';
});
JSFiddle
Or,
If it really bugs you, introduce your own jQuery method:
jQuery.fn.appendText = function(a){
return this.each(function(){
$(this).text(function(_,v){
return v += a;
});
});
};
For use like so:
$b.appendText(', World!!');
JSFiddle
'This seams like something jQuery would have existing functionality for, as vanilla JavaScript can do it by direct access to the property.'
Is probably exactly why jQuery doesn't implement its own method to do so. Why waste valuable bytes with a method that will carry out something that is so easily done with vanilla JavaScript?
use text()
$('b').text("Hello");
We need to be aware that this method escapes the string provided as
necessary so that it will render correctly in HTML. To do so, it calls
the DOM method .createTextNode(), which replaces special characters
with their HTML entity equivalents (such as < for <)
When you use .text() jQuery uses createTextNode internally, which escapes all special characters.

javascript onclick apostrophe quotation mark issue

Ok, I'm getting some data from an ajax call and need to store the value as a parameter to an onclick element via javascript.
Eg
output = "<a href = '#' onclick = 'deleteFileName('" + trim(splitString[i]) + "')'> delete File </a>";
This behaves strangely. When I inspect the element with chrome, the output looks like this
<a href="#" onclick="deleteFileName("0design mockup.xlsx')'> delete File </a>
It should obviously look like this
<a href = "#" onclick = "deleteFileName('0design mockup.xlsx')">
The parameter is a String so I need the quotes around it. This may not be the best way to do this, but why is it making the first two quotes double quotes and then the last two single quotes?
*This is a JSP server using ajax calls to gather information. The function "deleteFileName(fileNameIn)" is an ajax call. (I don't believe this is necessary information but you never know)
You can not use the same kinds of quotes for the value of onclick and for the function call. You need single quotes for one and double quotes for the other (where to put which should not matter). Otherwise you are closing the onclick attribute with the first single quote of the function call.
Example:
output = "<a href = '#' onclick = 'deleteFileName(\"" + trim(splitString[i]) + "\")'> delete File </a>";
Rather than inspecting the information, I suggest that you wget or curl the page directly (or use the browser's view-source function). These days I've found that many browsers present information subtly incorrectly in the inspector in their attempt to format everything nicely.
Removing the browser from the equation is a good first step, since that will show you exactly where the problem is occuring.

Categories

Resources