Given a web page with JavaScript code, I would like to generate a resulting html automatically (either via CLI tool OR using some library in some language)
For example, given test.html
<!DOCTYPE html>
<html>
<body>
<p id="demo"></p>
<script>
document.getElementById("demo").innerHTML = "Hello JavaScript!";
</script>
</body>
</html>
I would like to get as a result
<html>
<body>
<p id="demo">Hello JavaScript!</p>
<script>
document.getElementById("demo").innerHTML = "Hello JavaScript!";
</script>
</body>
</html>
After a quick search, it looks like watin will do what you want.
It's aimed at automated testing, but when it hits a page it will execute all js as well as ajax calls etc. Looks like you can grab the resulting html from it too.
The answer is based on the comment of #torazaburo
In fact, the phantomjs is capable of evaluating javascript and producing html.
Here is how it could look like, executing phantomjs load_page.js path_to/test.html
var page = require('webpage').create(),
system = require('system'),
page_address;
var fs = require('fs');
if (system.args.length === 1){
console.log('Usage: phantomjs ' + system.args[0] + ' <page_to_load:http://www.google.com>');
phantom.exit();
}
page_address = system.args[1]
page.open(page_address, function(status){
console.log('Status:' + status);
if (status === 'success' ){
fs.write('phantom_result.html', page.content, 'w')
}
phantom.exit();
});
Related
While building a chat application in Django, I used embedded javascript and it worked. But, if I write the same code in external javascript then the WebSocket gets closed. I have checked all the links and static file path. The script is loaded completely but the WebSockets gets closed after they open.
Here's the tutorial from Official Django Channels website, and that javascript is working in embedded form only not in an external script.
And, here's my Github repo where I've implemented Websockets.
How can I write JS code in external script instead of embedded? I've Googled but found no help and even this question hasn't been answered yet.
Here's the code I'm talking about and the websockets won't work if defined externally:
<!-- chat/templates/chat/room.html -->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>Chat Room</title>
</head>
<body>
<textarea id="chat-log" cols="100" rows="20"></textarea><br/>
<input id="chat-message-input" type="text" size="100"/><br/>
<input id="chat-message-submit" type="button" value="Send"/>
</body>
<script>
var roomName = {{ room_name_json }};
var chatSocket = new WebSocket(
'ws://' + window.location.host +
'/ws/chat/' + roomName + '/');
chatSocket.onmessage = function(e) {
var data = JSON.parse(e.data);
var message = data['message'];
document.querySelector('#chat-log').value += (message + '\n');
};
chatSocket.onclose = function(e) {
console.error('Chat socket closed unexpectedly');
};
document.querySelector('#chat-message-input').focus();
document.querySelector('#chat-message-input').onkeyup = function(e) {
if (e.keyCode === 13) { // enter, return
document.querySelector('#chat-message-submit').click();
}
};
document.querySelector('#chat-message-submit').onclick = function(e) {
var messageInputDom = document.querySelector('#chat-message-input');
var message = messageInputDom.value;
chatSocket.send(JSON.stringify({
'message': message
}));
messageInputDom.value = '';
};
</script>
</html>
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
});
})
Long-time user, first-time asker. I've learned so much from the community and I love this site.
So here is what I'm shooting for. I want to have a web interface that runs ping commands on the backend. I ideally want a website that has a text input that allows you to enter an IP address or domain, a button that runs the command and a python script that runs from PHP to actually run the ping command. The tricky part for was to get the output to print to the website live as it is outputted on the command line. I want to do it this way as a way to future-proof the concept and eventually use different iperf parameters.
I built a little PHP page that "technically" gets the job done but I can't figure out how to only call the PHP script when the button is clicked. Since it's a PHP page, it runs whenever the page is loaded. So after some research, I figure ajax jquery is what I'm looking for. I've spent about 2 days trying different things that get me really close but it seems that I'm dancing around my solution.
From what I've learned about ajax, I essentially need a button that runs an ajax function that is linked to my working php script. I can get it to run the script but I can't get it to update the page content in a live/continuous manner. Only when the command is finished running.
Here is my php page that does what it needs to do but does it everytime the page is loaded/reloaded. Not ideal. I want the script to only run when the button is pressed.
liveping.php:
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<form action="liveping.php" id="ping" method="post" name="ping">
Domain/IP Address: <input name="domain" type="text"> <input name="ping" type="submit" value="Ping">
</form><?php
if (isset($_POST['ping'])) {
function liveExecuteCommand($cmd)
{
while (# ob_end_flush()); // end all output buffers if any
$proc = popen("$cmd 2>&1", 'r');
$live_output = "";
$complete_output = "";
while (!feof($proc))
{
$live_output = fread($proc, 4096);
$complete_output = $complete_output . $live_output;
echo "<pre>$live_output</pre>";
# flush();
}
pclose($proc);
}
}
$domain = $_POST['domain'];
$pingCmd = "python /var/www/html/ping.py ".$domain;
if (isset($_POST['ping'])) {
liveExecuteCommand($pingCmd);
}
?>
</body>
</html>
ping.py:
#!/usr/bin/python
import cgi
import os
import sys
ping = "ping -c 5 -W 2 "+sys.argv[1]
os.system(ping)
Some things I've tried:
<html>
<head>
<script>
var ajax = new XMLHttpRequest();
ajax.onreadystatechange = setInterval(function() {
if (ajax.readyState == 4) {
document.getElementById('content').innerHTML = ajax.responseText;
}
},100);
function updateText() {
ajax.open('GET', 'ajax.php');
ajax.send();
}
</script>
</head>
<body>
<button onclick="updateText()">Click Me</button>
<div id="content">Nothing here yet.</div>
</body>
</html>
OR
<!DOCTYPE html>
<html>
<body>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.0/jquery.min.js"></script>
<script type="text/javascript">
var auto_refresh = setInterval(
function ()
{
$('#load_tweets').load('ajax.php').fadeIn("slow");
}, 1000); // refresh every 10000 milliseconds
</script>
</head>
<div id="load_tweets"> </div>
</body>
</html>
WITH ajax.php
<?php
while (# ob_end_flush()); // end all output buffers if any
$proc = popen("ping -c 5 -W 2 google.com", 'r');
$live_output = "";
$complete_output = "";
while (!feof($proc))
{
$live_output = fread($proc, 4096);
$complete_output = $complete_output . $live_output;
echo "<pre>$live_output</pre>";
# flush();
}
pclose($proc);
?>
Thanks for any help!
You do not need python for showing ping results. Just two PHP files will be enough.
index.php will have the AJAX functionalities along with the form.
ajax.php will have the code to ping specified domain address.
I afraid that using jQuery you might not able to catch the live feed. Because it doesn't have any onreadystatechange. So, you might need to use vanilla JavaScript in this case. Here is a working demonstration:
index.php:
<!DOCTYPE html>
<html>
<head>
<title>Ping AJAX</title>
</head>
<body>
<div>
Domain/IP Address: <input id="domain" type="text">
<input id="ping" type="button" value="Ping">
</div>
<div id="result"></div>
<script>
function updateText(domain) {
var ajax = new XMLHttpRequest();
ajax.onreadystatechange = function() {
if (this.readyState == 3) {
var old_value = document.getElementById("result").innerHTML;
document.getElementById("result").innerHTML = this.responseText;
}
};
var url = 'ajax.php?domain='+domain;
ajax.open('GET', url,true);
ajax.send();
}
document.getElementById("ping").onclick = function(){
domain = document.getElementById("domain").value;
updateText(domain);
}
</script>
</body>
</html>
ajax.php:
<?php
if (isset($_GET['domain'])) {
function liveExecuteCommand($cmd)
{
while (# ob_end_flush()); // end all output buffers if any
$proc = popen($cmd, 'r');
$live_output = "";
$complete_output = "";
while (!feof($proc))
{
$live_output = fread($proc, 4096);
$complete_output = $complete_output . $live_output;
echo "<pre>$live_output</pre>";
# flush();
}
pclose($proc);
}
$domain = $_GET['domain'];
$pingCmd = "ping ".$domain;
liveExecuteCommand($pingCmd);
}
else{
echo "No post request";
}
?>
Output:
Declaimer:
The ping command is changed as I am currently using Windows operating system. Update it according to your operating system.
As a first time questioner, you have described the problem neatly and also showed your efforts to solve the problem. I really appreciate it.
ajax.readyState == 4
essentially means, script on the other side has finished ... 3 is partial.
https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/readyState
You just have to take all ajax script into the function
example:
function updateText() {
$.ajax({
type: 'GET', // can be POST, too
url: "ajax.php",
crossDomain: true,
data: {
firstvar: firstvar,
secondvar: secondvar
},
cache: false,
success: function(data) {
if($.trim(data) == "false") {
alert("Fail to recived data");
}
else {
// Success getting data
// Do some jobs
}
}
});
}
If you want to cancel submit to not refesh, U can use
return false; // At the end of the function above
Hope it helps.
I have the following code below :
<!DOCTYPE html>
<html>
<head>
<script src="http://connect.soundcloud.com/sdk.js"></script>
<script>
SC.initialize({
client_id: "f520d2d8f80c87079a0dc7d90db9afa9"
});
SC.get("/users/3207",{}, function(user){
console.log("in the function w/ " + user);
});
</script>
</head>
</html>
The code should print the user name to the console however whenever I run this, my console gives the error of :
Failed to load resource: The requested URL was not found on this server:
file://api.soundcloud.com/users/3207?client_id=f520d2d8f80c87079a0dc7d90db9afa9&format=json&_status_code_map%5B302%5D=200
However if I were to directly http://api.soundcloud.com/users/3207.json?client_id=f520d2d8f80c87079a0dc7d90db9afa9, then I get a valid JSON result.
Is there something incorrect with my how I am using the SC.get function?
Thanks
Well, you should test your index.html locally on a web-server like Apache and not by opening it as a file.
Working example
SC.initialize({
client_id: "f520d2d8f80c87079a0dc7d90db9afa9"
});
SC.get("/users/3207", {}, function(user) {
console.log("in the function w/ " + JSON.stringify(user));
var res = document.getElementById("result");
res.innerHTML = JSON.stringify(user);
});
<script src="http://connect.soundcloud.com/sdk.js"></script>
<div id="result"></div>
I was following along the tutorial at http://nowjs.com/doc when I encountered some errors.
<html>
<head>
<title>index.html</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js"/>
<script src="http://localhost:8080/NowJS/now.js"></script>
<script>
$(document).ready(function(){
var name = prompt("what is your name?","");
now.receiveMessage = function(name,message){
alert(name+" "+message);
};
$('.butt').click(function(){
alert($('#put').val());
now.distributeMessage(name,$('#put').val());
$('#put').val('');
});
});
</script>
and for the server:
var fs = require('fs');
var sys = require('sys');
var server = require('http').createServer(function(req,response){
fs.readFile('index.html',function(err,data){
response.writeHead(200);
response.write(data);
response.end();
});
});
server.listen(8080);
sys.print('woot');
var everyone = require('now').initialize(server);
everyone.now.distributeMessage = function(name, message){
sys.print(name+" "+message);
everyone.now.receiveMessage(name,message);
};
I highly suspect it has something to do with my tag since there isnt anything at /NowJS/now.js.
Can someone enlighten me on this part:
On pages that you would like to use NowJS on, simply include this script tag in your HTML head: NowJS only works on pages that are served through the same http server instance that was passed into the initialize function above.
Thanks for your time.
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js"/>
script tags can't be self-closed.
In the docs the path in the script tag is lower-case, /nowjs/now.js, whereas in your snippet it is /NowJS/now.js, and so I guess this is the reason it doesn't work.