How to send response with javascript to draw html elements - javascript

I'm creating a script like twitter in which user just provide an id and all his/her tweets get loaded on site where the script inserted.
What I've done is
User should copy this code to load my widget
<a class="getStarted" data-getStartedID="123456789">Get Started App ID</a>
<script>
!function(d,s,id){
var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';
if(!d.getElementById(id)){
js=d.createElement(s);
js.id=id;
js.src=p+"://localhost/practices/js_practice/siteOpen.js";
fjs.parentNode.insertBefore(js,fjs);
}}(document,"script","getStarted-C");
My siteOpen.js is as below :
!function(d){
var a = d.getElementsByClassName('getStarted');
var x = document.getElementsByClassName("getStarted")[0].getAttribute("data-getStartedID");
var r = new XMLHttpRequest();
var appID = x;
r.open("POST", "openwebIndex.php", true);
r.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
r.setRequestHeader("Content-length", appID.length);
r.setRequestHeader("Connection", "close");
r.onreadystatechange = function () {
if (r.readyState != 4 || r.status != 200) return;
if(r.responseText.trim()==1){
return '<p>output to be draw on where script is pasted</p>';
if(console)console.info('Valid appID');
}
};
r.send('appID='+appID);
}(document);
i don't know what to do to send the response and load/draw my widget on user's website.
My response will be in html elements.
Please suggest me what should i do. I just stuck at this point.
EDIT
I'm getting object HTMLScriptElement when I alert js variable.

Just trying adding the html code in the body tag.
users html file
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
</body>
</html>
<script src="widget.js"></script>
Your widget.js
// var appId = d.getElementsByClassName('getStarted');
// process the app id and make the output here
var output = "<div>This is the content of the widget</div>";
document.body.innerHTML += output;
This will show the content in the users html file. If you have cross domain issue, use JSONP for resolving that.

Related

Cannot reproduce query param html injection

We have an embedded script running on the page of one our clients. We received a report from them that the query params we send to that page are not properly guarded against XSS injection.
When I try a url like:
https://www.clientsite.com?somekey=%3Csvg%20onload%3Dalert(document.cookie)%3E
on their site, I indeed get the alert panel displaying the cookies.
But when I run our script locally, I cannot reproduce this injection. The alert panel never shows up, no matter what I put in the query param's value.
A very simplified version of the script is:
<html lang="en">
<head>
<meta charset="utf-8">
<title>XSS test</title>
</head>
<body>
<div id="content"></div>
<script>
(function() {
var url = window.location.href
var someKey = 'somekey'
var regexS = "[\\?&]"+someKey+"=([^&#]*)";
var regex = new RegExp(regexS);
var results = regex.exec(url);
var parentElement = document.querySelector('#content');
var widget = document.createElement('div');
// var svgInjection = '<svg onload=alert("alert!!")>'
// var svgEncodedInjection = '%3Csvg%20onload%3Dalert("alert!!")%3E'
widget.innerHTML = '<div>' + results[1] + '</div>';
return parentElement.insertBefore(widget, parentElement.firstChild);
})()
</script>
</body>
</html>
I don't understand how an identical script, receiving identical query params, shows an alert panel on the client's site, and nothing when I run it locally. Any thoughts?

script in HTML string is not executed when passed via JSON

This is a follow-up question of this one.
Goal is to use some user input that is converted to a HTML document that should be displayed in a new tab (that's answered in the link above).
Problem is, however, that - if the HTML document contains <script> tags - those are not executed when this HTML string is passed as JSON. Below I use a simple string:
'<!DOCTYPE html><title>External html</title><div>Externally created</div><script>alert("WORKING");</script>'
This is a minimal example to illustrate the problem (you will see this in your browser when you load the HTML from below):
When I click on the button, the new tab is opened but the script is not executed i.e. there is no alert shown. By clicking on the alert link, the html string is loaded directly and the alert is shown correctly.
My question is, how to postprocess the HTML string that is returned from .getJSON to execute the script correctly. Currently I do it like this (entire code can be found below):
$.get('/_process_data', {
some_data: JSON.stringify('some data'),
}).success(function(data) {
var win = window.open("", "_blank");
win.document.body.innerHTML = data;
})
This is my code:
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
</head>
<body>
<div class="container">
<div class="header">
<h3 class="text-muted">Get new tab!</h3>
</div>
<button type="button" id="process_input">no alert</button>
<a href="/html_in_tab" class="button" target='_blank'>alert</a>
</div>
<script src="https://code.jquery.com/jquery-1.12.4.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function() {
$('#process_input').bind('click', function() {
$.get('/_process_data', {
some_data: JSON.stringify('some data'),
}).success(function(data) {
var win = window.open("", "_blank");
win.document.body.innerHTML = data;
})
return false;
});
});
</script>
</body>
</html>
and the flask file:
from flask import Flask, render_template, request, jsonify
import json
# Initialize the Flask application
app = Flask(__name__)
#app.route('/html_in_tab')
def get_html():
# provided by an external tool
# takes the user input as argument (below mimicked by a simple string concatenation)
return '<!DOCTYPE html><title>External html</title><div>Externally created</div><script>alert("WORKING");</script>'
#app.route('/_process_data')
def data_collection_and_processing():
# here we collect some data and then create the html that should be displayed in the new tab
some_data = json.loads(request.args.get('some_data'))
# just to see whether data is retrieved
print(some_data)
# oversimplified version of what actually happens; get_html comes from an external tool
my_new_html = get_html() + '<br>' + some_data
print(my_new_html)
# this html should now be displyed in a new tab
return my_new_html
#app.route('/')
def index():
return render_template('index_new_tab.html')
if __name__ == '__main__':
app.run(debug=True)
I think you need something like this:
var win = window.open("", "_blank",);
win.document.write('<!DOCTYPE html><title>External html</title><div>Externally created</div><script>(function(){alert(1);})();</script>');
when you open the popup, this executes JavaScript. You could add data and do whatever you want inside <script>(function(){alert(data);})();</script>
After the HTML has been added to the page, you could execute a function to run it. This would require wrapping your scripts with functions like this:
function onStart() {
// Your code here
}
Then after the HTML is added to the page, run the function:
$.get('/_process_data', {
some_data: JSON.stringify('some data'),
}).success(function(data) {
var win = window.open("", "_blank");
win.document.body.innerHTML = data;
onStart();
})
Instead of...
var win = window.open("", "_blank");
win.document.body.innerHTML = data;
Use jquery to load the html and wait for loading to complete:
$.get('/_process_data', {
some_data: JSON.stringify('some data'),
}).success(function(data) {
var w = window.open("", "_blank");
$(w.document.body).load(data, function () {
//execute javascript here
});
})

Customize DocxJS to render local docx file

I just found a working docx to html converter using only javascript on github. The main code which converts docx to html is below. The issue is the page just has a button which on click or drag and choosing a word document, opens it as html. I want to specify a file location in the code so I can load it on the server for loading some documents from computer locally.
Code which converts docx to html and renders :
<html lang="en">
<head>
<meta charset="UTF-8">
<title>DocxJS Example</title>
<script type="text/javascript" src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
<script type="text/javascript" src="https://www.docxjs.com/js/build/latest.docxjs.min.js"></script>
</head>
<body>
<input id="inputFiles" type="file" name="files[]" multiple="false">
<div id="loaded-layout" style="width:100%;height:800px;"></div>
<script>
$(document).ready(function(){
var $inputFiles = $('#inputFiles');
$inputFiles.on('change', function (e) {
var files = e.target.files;
var docxJS = new DocxJS();
docxJS.parse(
files[0],
function () {
docxJS.render($('#loaded-layout')[0], function (result) {
if (result.isError) {
console.log(result.msg);
} else {
console.log("Success Render");
}
});
}, function (e) {
console.log("Error!", e);
}
);
});
});
</script>
</body>
</html>
I tried changing var files = e.target.files; to var files = "C:/sda/path/to/docx"; but that didn't help.
I tried to change
var files = e.target.files;
to
var files = new Array(new File([""], "sample.docx"));
but it gives me OOXML parse error.
Update:
Lets say I have a file location variable in PHP and I wish to use that instead in the javascript code. How do I do it?
I also checked docx2html javascript code and here is the code for it:
<!DOCTYPE html>
<html>
<head>
<script src="index.js"></script>
<script>
function test(input){
require("docx2html")(input.files[0]).then(function(converted){
text.value=converted.toString()
})
}
</script>
</head>
<body>
<input type="file" style="position:absolute;top:0" onchange="test(this)">
<br/>
<br/>
<textarea id="text"></textarea>
</body>
</html>
Same issue need input.files[0] here as well
Update:
I am trying to use the method mentioned in the comments but encounter some errors:
var fil;
var getFileBlob = function (url, cb) {
var xhr = new XMLHttpRequest();
xhr.open("GET", url);
xhr.responseType = "blob";
xhr.addEventListener('load', function() {
cb(xhr.response);
});
xhr.send();
};
var blobToFile = function (blob, name) {
blob.lastModifiedDate = new Date();
blob.name = name;
return blob;
};
var getFileObject = function(filePathOrUrl, cb) {
getFileBlob(filePathOrUrl, function (blob) {
cb(blobToFile(blob, 'test.docx'));
});
};
getFileObject('demo.docx', function (fileObject) {
console.log(fileObject);
fil = fileObject;
});
The error primarily was “Cross origin requests are only supported for HTTP.” before I used https://calibre-ebook.com/downloads/demos/demo.docx instead of just demo.docx in above file path. This however gives another error:
Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https, chrome-extension-resource.
which means chrome cannot load it. It needs to be working on a server. If someone can help providing a fix to make it work offline, let me know. The last method was asynchronous call.
In the browser, there is a sandbox policy.
It can not access files directly via Path.
Please access the file through drag & drop event or input file change event.

YouTube API -- extracting title and videoId attributes to build hyperlink

The following is a JavaScript file that searches through YouTube video data using its API. Down at the bottom you'll see the onSearchResponse() function, which calls showResponse(), which in turn displays the search results.
As this code from Codecademy stands, a HUGE amount of information gets printed relating to my search term.
Instead of all that, can I simply display a hyperlink using the title and videoId attributes? How would I go about altering responseString in showResponse() to build that link? Thank you!
// Your use of the YouTube API must comply with the Terms of Service:
// https://developers.google.com/youtube/terms
// Helper function to display JavaScript value on HTML page.
function showResponse(response) {
var responseString = JSON.stringify(response, '', 2);
document.getElementById('response').innerHTML += responseString;
}
// Called automatically when JavaScript client library is loaded.
function onClientLoad() {
gapi.client.load('youtube', 'v3', onYouTubeApiLoad);
}
// Called automatically when YouTube API interface is loaded (see line 9).
function onYouTubeApiLoad() {
// This API key is intended for use only in this lesson.
// See link to get a key for your own applications.
gapi.client.setApiKey('AIzaSyCR5In4DZaTP6IEZQ0r1JceuvluJRzQNLE');
search();
}
function search() {
// Use the JavaScript client library to create a search.list() API call.
var request = gapi.client.youtube.search.list({
part: 'snippet',
q: 'clapton'
});
// Send the request to the API server,
// and invoke onSearchRepsonse() with the response.
request.execute(onSearchResponse);
}
// Called automatically with the response of the YouTube API request.
function onSearchResponse(response) {
showResponse(response);
console.log(response);
}
Here is the corresponding HTML file:
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="stylesheets/styles.css">
<meta charset="UTF-8">
<title>My YouTube API Demo</title>
</head>
<body>
<section>
<div id="response"></div>
</section>
<script src="javascripts/search-2.js"></script>
<script src="https://apis.google.com/js/client.js?onload=onClientLoad" type="text/javascript"></script>
</body>
</html>
Your advice is much appreciated!
I think it might be what you are exactly trying to do.
function showResponse(response) {
var html = response.items.map(itemToHtml);
document.getElementById('response').innerHTML += html;
}
function itemToHtml(item) {
var title = item.snippet.title;
var vid = item.id.videoId;
return generateHyperlink(title, vid);
}
function generateHyperlink(title, vid) {
return '' + title + '<br/>';
}
This code show up links named title having YouTube video link using videoId.

Javascript - Reading file in client directory

I'm a new programmer that learn javascript, Im new in js actually.
I have a task that require a web page able to read file in client directory. I've got some js code :
<html>
<script type="text/javascript">
function ReadWeight() {
var filePath = "file:///D:/Text.txt";
var xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET",filePath,false);
xmlhttp.send(null);
var fileContent = xmlhttp.responseText;
alert(fileContent);
}
ReadWeight();
</script>
<body>
</body>
</html>
When I save this code in my directory and access it by this link, It works well.
file:///D:/test.html
But when I put it in my localhost and I access it, the JS doesn't works.
Does my code incorrect when in web server?
Please help me out.
Might I suggest using an error console to display the error so people know how to help you? =] And paste it in your query
Download something like firebug and see if a request is being made (for FireFox)
It looks like you would rather want to access the file via the http:// protocol, instead of file://
As far as I know you can only read client files using an <input type="file"> element. Once you get the file you can read it multiple times:
HTML:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>File Refresh</title>
<script src="filerefresh.js"></script>
</head>
<body>
<input id="fileInput" type="file">
<pre id="fileDisplay"></pre>
</body>
</html>
JavaScript:
(function() {
var sleepInterval = 1000; // 1 second
var fileInput;
var fileDisplay;
var reader;
var id = undefined;
function initialize() {
fileInput = document.getElementById("fileInput");
fileDisplay = document.getElementById("fileDisplay");
reader = new FileReader();
reader.onloadend = function() {
fileDisplay.innerHTML = reader.result;
reschedule();
};
fileInput.addEventListener("change", readFile);
}
function reschedule() {
if (id !== undefined) {
clearTimeout(id);
}
id = setTimeout(readFile, sleepInterval);
}
function readFile() {
reader.readAsText(fileInput.files[0]);
}
window.onload = initialize;
})();

Categories

Resources