Sending all Javascript console output into a DOM element - javascript

How does one send all console output into a DOM element so it can be viewed without having to open any developer tools? I'd like to see all output, such as JS errors, console.log() output, etc.

I found the accepted answer above helpful but it does have a couple issues as indicated in the comments:
1) doesn't work in Chrome because "former" does not take into account the this context no long being the console, the fix is to use the JavaScript apply method.
2) It does not account for multiple arguments being passed to console.log
I also wanted this to work without jQuery.
var baseLogFunction = console.log;
console.log = function(){
baseLogFunction.apply(console, arguments);
var args = Array.prototype.slice.call(arguments);
for(var i=0;i<args.length;i++){
var node = createLogNode(args[i]);
document.querySelector("#mylog").appendChild(node);
}
}
function createLogNode(message){
var node = document.createElement("div");
var textNode = document.createTextNode(message);
node.appendChild(textNode);
return node;
}
window.onerror = function(message, url, linenumber) {
console.log("JavaScript error: " + message + " on line " +
linenumber + " for " + url);
}
Here is an updated working example with those changes.
http://jsfiddle.net/eca7gcLz/

This is one approach for a quick solution:
Javascript
var former = console.log;
console.log = function(msg){
former(msg); //maintains existing logging via the console.
$("#mylog").append("<div>" + msg + "</div>");
}
window.onerror = function(message, url, linenumber) {
console.log("JavaScript error: " + message + " on line " +
linenumber + " for " + url);
}
HTML
<div id="mylog"></div>
Working Example http://jsfiddle.net/pUaYn/2/

Simple console.log redefinition, without error handling:
const originalConsoleLog = console.log
console.log = (...args) => {
args.map(arg => document.querySelector("#mylog").innerHTML += arg + '<br>')
}
console.log = originalConsoleLog

Related

Looking for alternative of javscript eval function [duplicate]

This question already has answers here:
How do I include a JavaScript file in another JavaScript file?
(70 answers)
Closed 2 years ago.
I am using the following function to make an XHR request and execute javascript from the response if possible:
function ajaxRequest(resultDiv, processing, action, paramName, param, paramName2, param2, parseJs) {
if (processing) {
document.getElementById(resultDiv).innerHTML = processing;
}
var xmlhttp = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");
xmlhttp.onreadystatechange = function() {
if (this.readyState === 4 && this.status === 200) {
var resp = this.responseText;
document.getElementById(resultDiv).innerHTML = resp;
if (parseJs) {
parseScript(resp);
}
}
}
if (paramName2) {
xmlhttp.open("GET", "/query?" + paramName + "=" + param + "&" + paramName2 + "=" + param2 + "&action=" + action, true);
} else {
xmlhttp.open("GET", "/query?" + paramName + "=" + param + "&action=" + action, true);
}
xmlhttp.send();
}
function parseScript(strcode) {
var scripts = new Array();
while (strcode.indexOf("<script") > -1 || strcode.indexOf("</script") > -1) {
var s = strcode.indexOf("<script");
var s_e = strcode.indexOf(">", s);
var e = strcode.indexOf("</script", s);
var e_e = strcode.indexOf(">", e);
scripts.push(strcode.substring(s_e + 1, e));
strcode = strcode.substring(0, s) + strcode.substring(e_e + 1);
}
for (var i = 0; i < scripts.length; i++) {
try {
eval(scripts[i]);
} catch (ex) {
alert("Error while executing");
}
}
}
But I got to know that eval function is somehow dangerous and very slow. So can you help me to find something alternative of eval and rewrite the code snippet to work same way it meant to be but with alternative of eval? Thanks in advance, and sorry for my bad English.
An alternative to eval() might be to inject the code into a <script> tag on your page, upon which it is then immediately executed.
In the example below, the code is provided to script.text. For a URL as in your question, use script.src instead.
const script = document.createElement('script');
script.text = 'console.log("foo");';
document.body.append(script);
// logs "foo"
Eval can be slow but is as dangerous as any other solution if you are running code that is not trusted or verified by yourself. If you do need another way to run this you can try dynamic script text insertion as described in the answer here

How to convert string from [object HTMLDocument] in android or java

I am developing a customized gecko powered android browser. I want to print the source code in console.
When I try to print it shows [object HTMLDocument].
The code is given below :
function onPageLoad(event) {
// the target is an HTMLDocument
let contentDocument = event.target;
let browser = BrowserApp.getBrowserForDocument(contentDocument);
console.log("Page loaded: " + browser.contentTitle);
console.log("Page loaded content: " + browser.contentDocument);
}
The output is Page loaded content: [object HTMLDocument]
I want to print the source code in [object HTMLDocument].
Ah, I see. Try:
let contentDocument = event.target;
console.log("Page loaded: " + contentDocument.title);
var s = new XMLSerializer().serializeToString(contentDocument);
console.log("Page loaded content: " + s);
This worked for me at least (if I understand correctly what you want to print that is).
Have you tried converting it to a String? For example, console.log("Page loaded: " + String(browser.contentTitle));
Try this:
HTMLEditorKit tmp = new HTMLEditorKit();
HTMLDocument doc = (HTMLDocument) tmp.createDefaultDocument();
StringWriter writer = new StringWriter();
tmp.write(writer, doc, 0, doc.getLength());
String s = writer.toString();
console.log(s);
I hope it will help.
Put , instead of + in console.log() function as console.log() also support object. Just you need to separate by comma.
console.log("Page loaded: " , browser.contentTitle);
console.log("Page loaded content: " , browser.contentDocument);

Node.js net library: getting complete data from 'data' event

I've searched around, and either can't find the exact question I'm trying to answer, or I need someone to explain it to me like I'm 5.
Basically, I have a Node.js script using the Net library. I'm connecting to multiple hosts, and sending commands, and listening for return data.
var net = require('net');
var nodes = [
'HOST1,192.168.179.8',
'HOST2,192.168.179.9',
'HOST3,192.168.179.10',
'HOST4,192.168.179.11'
];
function connectToServer(tid, ip) {
var conn = net.createConnection(23, ip);
conn.on('connect', function() {
conn.write (login_string); // login string hidden in pretend variable
});
conn.on('data', function(data) {
var read = data.toString();
if (read.match(/Login Successful/)) {
console.log ("Connected to " + ip);
conn.write(command_string);
}
else if (read.match(/Command OK/)) { // command_string returned successful,
// read until /\r\nEND\r\n/
// First part of data comes in here
console.log("Got a response from " + ip + ':' + read);
}
else {
//rest of data comes in here
console.log("Atonomous message from " + ip + ':' + read);
}
});
conn.on('end', function() {
console.log("Lost conncection to " + ip + "!!");
});
conn.on('error', function(err) {
console.log("Connection error: " + err + " for ip " + ip);
});
}
nodes.forEach(function(node) {
var nodeinfo = node.split(",");
connectToServer(nodeinfo[0], nodeinfo[1]);
});
The data ends up being split into two chunks. Even if I store the data in a hash and append the first part to the remainder when I read the /\r\nEND\r\n/ delimiter, there's a chunk missing out of the middle. How do I properly buffer the data in order to make sure I get the complete message from the stream?
EDIT: Ok, this seems to be working better:
function connectToServer(tid, ip) {
var conn = net.createConnection(23, ip);
var completeData = '';
conn.on('connect', function() {
conn.write (login_string);
});
conn.on('data', function(data) {
var read = data.toString();
if (read.match(/Login Successful/)) {
console.log ("Connected to " + ip);
conn.write(command_string);
}
else {
completeData += read;
}
if (completeData.match(/Command OK/)) {
if (completeData.match(/\r\nEND\r\n/)) {
console.log("Response: " + completeData);
}
}
});
conn.on('end', function() {
console.log("Connection closed to " + ip );
});
conn.on('error', function(err) {
console.log("Connection error: " + err + " for ip " + ip);
});
}
My biggest problem was apparently a logic error. I was either waiting for the chunk that began the reply, or the chunk that ended it. I wasn't saving everything in-between.
I guess if I wanted to get all Node-ish about it, I should fire an event whenever a complete message came in (beginning with a blank line, ending with 'END' on a line by itself), and do the processing there.
You shouldn't do anything with the data you recieve, until you receive the end event. The end callback means that all data chunks have been sent through the stream to your callbacks. If data comes in more than one chunk, you need to create a variable within your function closure to store this data to. Most programs can work just fine ignoring this fact, because data usually comes across in one chunk. But sometimes it doesn't. It doesn't even necessarily depend on the amount of data. If you're in a situation where this is happening, I created an example that demos how to handle it. I basically used your code, but removed all the fluff... this is just demoing the logic you need to collect all the data and do work on it.
function connectToServer(tid, ip) {
var conn = net.createConnection(23, ip);
var completeData = '';
conn.on('connect', function() {
conn.write (login_string); // login string hidden in pretend variable
});
conn.on('data', function(data) {
completeData += data;
var dataArray = completeData.split('your delimiter');
if(dataArray.size > 1) { //If our data was split into several pieces, we have a complete chunk saved in the 0th position in the array
doWorkOnTheFirstHalfOfData(dataArray[0]);
completeData = dataArray[1];// The second portion of data may yet be incomplete, thise may need to be more complete logic if you can get more than one delimeter at a time...
}
});
conn.on('end', function() {
//do stuff with the "completeData" variable in here.
});
}
My problem was a logic problem. I was either looking for the chunk that began the message, or the chunk that ended the message, and ignoring everything in between. I guess expected the entirety of the reply to come in in one or two chunks.
Here's the working code, pasted from above. There's probably a more Node-ish way of doing it (I should really emit an event for each chunk of information), but I'll mark this as the answer unless someone posts a better version by this time tomorrow.
function connectToServer(tid, ip) {
var conn = net.createConnection(23, ip);
var completeData = '';
conn.on('connect', function() {
conn.write (login_string);
});
conn.on('data', function(data) {
var read = data.toString();
if (read.match(/Login Successful/)) {
console.log ("Connected to " + ip);
conn.write(command_string);
}
else {
completeData += read;
}
if (completeData.match(/Command OK/)) {
if (completeData.match(/\r\nEND\r\n/)) {
console.log("Response: " + completeData);
}
}
});
conn.on('end', function() {
console.log("Connection closed to " + ip );
});
conn.on('error', function(err) {
console.log("Connection error: " + err + " for ip " + ip);
});
}

Javascript: Event inside a function object created with the new keyword

I have a C# COM DLL ("This.That") that has events, which I've tested using JS and they work fine. I'm now trying to wrap all my tested code inside an object. The following example works fine:
var oTest = new Test();
function Test()
{
var oDevice = new ActiveXObject("This.That");
this.CancelOperation = function()
{
try
{
oDevice.CancelOperation();
return "CancelOperation successful.";
}
catch (e)
{
return e.message;
}
};
}
But once I try to add an event to it, it doesn't work. It looks like it's probably bad syntax. I can't find any resources online that explain how this is done.
var oTest = new Test();
function Test()
{
var oDevice = new ActiveXObject("This.That");
this.CancelOperation = function()
{
try
{
oDevice.CancelOperation();
return "CancelOperation successful.";
}
catch (e)
{
return e.message;
}
};
oDevice::DeviceStatusUpdate(wasSuccess, message, data) = function()
{
document.getElementById("outBox").value += "Success: " + wasSuccess.toString() + "\nMessage: " + message + "\nData:" + data + "\n\n";
};
}
I've gotten something working but I'd still like to see other answers. This puts the event handler outside of the JS file and into the document, but the code itself is still inside the JS file. The organization of the code was my greatest concern so this is acceptable to me.
var oTest = new Test();
function Test()
{
var oDevice = new ActiveXObject("This.That");
this.CancelOperation = function()
{
try
{
oDevice.CancelOperation();
return "CancelOperation successful.";
}
catch (e)
{
return e.message;
}
};
this.WireEvents = function()
{
var script = document.createElement("script");
script.type = "text/javascript";
script.text = 'function oTest.oDevice::DeviceStatusUpdate(wasSuccess, message, data) { document.getElementById("outBox").value += "Success: " + wasSuccess.toString() + "\\nMessage: " + message + "\\nData:" + data + "\\n\\n"; }';
document.body.appendChild(script);
};
}

Server Side Logging Of Client Side Javascript Crashes

I have a large complex web app with thousands of lines of Javascript. There is a small set of intermittent Javascript bugs that are report by users.
I think these are epiphenomena of race conditions - something has not initialised correctly and the Javascript crashes causing 'down stream' js not to run.
Is there anyway to get Javascript execution crashes to log back server side?
All the js logging libraries like Blackbird and Log4JavaScript are client-side only.
I have written a remote error logging function using window.onerror as suggested by #pimvdb
Err = {};
Err.Remoterr = {};
Err.Remoterr.onerror = function (msg, errorfileurl, lineno) {
var jsonstring, response, pageurl, cookies;
// Get some user input
response = prompt("There has been an error. " +
"It has been logged and will be investigated.",
"Put in comments (and e-mail or phone number for" +
" response.)");
// get some context of where and how the error occured
// to make debugging easier
pageurl = window.location.href;
cookies = document.cookie;
// Make the json message we are going to post
// Could use JSON.stringify() here if you are sure that
// JSON will have run when the error occurs
// http://www.JSON.org/js.html
jsonstring = "{\"set\": {\"jserr\": " +
"{\"msg\": \"" + msg + "\", " +
"\"errorfileurl\": \"" + errorfileurl + "\", " +
"\"pageurl\": \"" + pageurl + "\", " +
"\"cookies\": \"" + cookies + "\", " +
"\"lineno\": \"" + lineno + "\", " +
"\"response\": \"" + response + "\"}}}";
// Use the jquery cross-browser post
// http://api.jquery.com/jQuery.post/
// this assumes that no errors happen before jquery has initialised
$.post("?jserr", jsonstring, null, "json");
// I don't want the page to 'pretend' to work
// so I am going to return 'false' here
// Returning 'true' will clear the error in the browser
return false;
};
window.onerror = Err.Remoterr.onerror;
I deploy this between the head and body tags of the webpage.
You will want to change the JSON and the URL that you post it to depending on how you are going to log the data server side.
Take a look at https://log4sure.com (disclosure: I created it) - but it is really useful, check it out and decide for yourself. It allows you to log errors/event and also lets you create your custom log table. It also allows you to monitor your logs real-time. And the best part, its free.
You can also use bower to install it, use bower install log4sure
The set up code is really easy too:
// setup
var _logServer;
(function() {
var ls = document.createElement('script');
ls.type = 'text/javascript';
ls.async = true;
ls.src = 'https://log4sure.com/ScriptsExt/log4sure.min.js';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(ls, s);
ls.onload = function() {
// use your token here.
_logServer = new LogServer("use-your-token-here");
};
})();
// example for logging text
_logServer.logText("your log message goes here.")
//example for logging error
divide = function(numerator, divisor) {
try {
if (parseFloat(value) && parseFloat(divisor)) {
throw new TypeError("Invalid input", "myfile.js", 12, {
value: value,
divisor: divisor
});
} else {
if (divisor == 0) {
throw new RangeError("Divide by 0", "myfile.js", 15, {
value: value,
divisor: divisor
});
}
}
} catch (e) {
_logServer.logError(e.name, e.message, e.stack);
}
}
// another use of logError in window.onerror
// must be careful with window.onerror as you might be overwriting some one else's window.onerror functionality
// also someone else can overwrite window.onerror.
window.onerror = function(msg, url, line, column, err) {
// may want to check if url belongs to your javascript file
var data = {
url: url,
line: line,
column: column,
}
_logServer.logError(err.name, err.message, err.stack, data);
};
// example for custom logs
var foo = "some variable value";
var bar = "another variable value";
var flag = "false";
var temp = "yet another variable value";
_logServer.log(foo, bar, flag, temp);

Categories

Resources