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.
Related
I have this form that a user choose values from two dropdown menu. The options in select comes from js file and are exchange rates list. I have already created the code that should give me the result. But when i console.log it doesnt show anything, but the right data is displayed (echoed) in the php file. Right get is displayed in url also. I guess somewhere in the JS part is something wrong and i cant figure it out, i have already looked at other examples but they are all jquery.
HTML:
<!DOCTYPE html>
<html lang="sv">
<head>
<title>something</title>
<meta charset="utf-8">
<script src='plotly.min.js'></script>
<script type="text/javascript">
function loadDoc() {
var e = document.getElementById("searchlan");
var from = e.options[e.selectedIndex].value;
var e1 = document.getElementById("searchlan1");
var to = e1.options[e1.selectedIndex].value;
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function()
{
if (this.readyState == 4 && this.status == 200)
{
console.log(JSON.parse(this.responseText));
}
};
xhttp.open("GET", "server.php?from="+from+"&to="+to, true);
xhttp.send();
}
</script>
</head>
<body>
<div id="info">
<h2>Exchange rate</h2>
<form>
<p>
<select id="searchlan" name="from"></select>
<p>
<p>
<select id="searchlan1" name="to"></select>
<p>
<button onclick="loadDoc()" > show graph </button>
</p>
</form>
<div id="chartContainer"></div>
</div>
<script src="test.js"></script>
</body>
</html>
PHP:
require_once('index.php');
if(isset($_GET['from']) && isset($_GET['to'])){
//here i bring data from server using curl, it works fine and echoes the data
$curl = curl_init();
//this is the response variable
$obj= json_decode($response);
//i structure data
//Here i make it ready to be used in js
$data = [ [
"x" => $x,
"y" => $y,
"type" => "scatter"
] ];
$out = json_encode( $data );
echo "{$out}";
<button onclick="loadDoc()" > show graph </button>
When the submit button is clicked, the loadDoc function runs, but before the Ajax response arrives, the form submits and a new page is loaded.
The new page doesn't including the event handler waiting for the Ajax response.
Don't use a submit button. Add type="button".
I have solved it with help of Quentin. You guys can use this code, but remember to remove all of html that you have after your php code. it causes this error
Uncaught SyntaxError: row 23 Unexpected token < in JSON at position 4 at JSON.parse () at XMLHttpRequest.xhttp.onreadystatechange
if you get this, remove all of your html or anything you have after you echo the data you want to send to JS
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.
I am using a PHP Simple HTML DOM Parser to save a website as a htm file. I then use jQuery to extract a div from the file and put it into a div. I want to create a
Previous and Next button but the problem I have is that to do this I have to change the URL so the parser can get the page. I would really appreciate if you can help. Below is the code I am using.
<?php
include( 'site/simple_html_dom.php');
$html=file_get_html( 'http://roosterteeth.com/home.php?page=1');
$html->save('site/rtnews.htm')
?>
<script type="text/javascript" src="site/jquery.js"></script>
<script type="text/javascript">
$('document').ready(function() {
$('#wrap').click(function (event){
event.preventDefault();
});
$("#wrap").load('site/rtnews.htm #postsArea');
});
</script>
</head>
<body>
<div id="wrap">
</div>
</body>
You will have to create a new php file for this and make an AJAX request to that file. I assume you have already realised that you cannot make a cross-domain request due to CORS.
Here is your new php file, let's call it proxy.php. It will proxy the request, responding with the page that is passed to it via GET :
<?php
include( 'site/simple_html_dom.php');
$html=file_get_html( 'http://roosterteeth.com/home.php?page=' . $_GET["page"]);
echo $html;
?>
Your new JavaScript;
$('document').ready(function() {
var $wrap = $('#wrap'),
page = 1;
$('#next').on('click', function () {
getPage(++page);
});
$('#prev').on('click', function () {
getPage(--page);
});
var getPage = function (page) {
$wrap.load('proxy.php?page=' + page + ' #postsArea');
};
getPage(page);
});
In a prior post I was trying to upload a file to a server using HTML and Javascript. I ran into several problems with my implementation so I've taken a different approach. I have a HTML form and a python script in the cgi directory of my webserver. Here is my HTML code...
<html>
<head>
<script type="text/javascript">
function loadXMLDoc(){
var xmlhttp;
if (window.XMLHttpRequest){
// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else{
// code for IE6, IE5 seriously, why do I bother?
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function(){
if (xmlhttp.readyState==4 && xmlhttp.status==200){
document.getElementById("outputDiv").innerHTML=xmlhttp.responseText;
}
}
var file = document.getElementById('idexample').value;
xmlhttp.open("GET","/cgi/ajax.py?uploadFile="+file,true);
xmlhttp.send();
}
</script>
</head>
<body onload="changeInput()">
<form name = "form_input" enctype="multipart/form-data" method="POST">
<input type="file" ACCEPT="text/html" name="uploadFile" id="idexample" />
<button type="button" onclick="loadXMLDoc()">Enter</button>
</form>
<div id="outputDiv"></div>
</body>
</html>
I am using AJAX because it occured to me that my cgi script could take up to a couple of minutes to run depending on the file the user enters. What I'm trying to do is get the contents of the file passed to my python CGI script and print them out on the page. All I'm getting is "C:\fakepath\. What I want to do is get the file contents. Here is my cgi script...
#!/usr/bin/python
import cgi
form = cgi.FieldStorage()
print 'Content-Type: text/html\n'
if form.has_key('uploadFile'):
print str(form['uploadFile'].value)
else:
print 'no file'
Also should I be using
xmlhttp.open("POST","/cgi/ajax.py",true);
instead of
xmlhttp.open("GET","/cgi/ajax.py?uploadFile="+file,true);
I tried both but the POST one doesn't even return the name of my file. Also it occured to me that I read that I may not even need the tags in my script since I submit this information using javascript. Is this true. My page seems to work without the form tags (at least on Chrome and Firefox).
If you examine the variable file using console.log(), you will notice that it only contains the filename and not its contents.
var file = document.getElementById('idexample').value;
console.log(file); // Outputs filename
The standard way to upload a file via AJAX is to use an iframe. The following code is taken from jquery.extras.js and is based on malsup's form plugin.
<html>
<body>
<form id=input action=/cgi/ajax.py method=post>
<input type=file name=uploadFile>
<input type=submit value=Submit>
</form>
<div id=output></div>
<script src='https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js'></script>
<script>
$.fn.ajaxForm = function(options) {
options = $.extend({}, {
onSubmit:function() {},
onResponse:function(data) {}
}, options);
var iframeName = 'ajaxForm', $iframe = $('[name=' + iframeName + ']');
if (!$iframe.length) {
$iframe = $('<iframe name=' + iframeName + ' style="display:none">').appendTo('body');
}
return $(this).each(function() {
var $form = $(this);
$form
.prop('target', iframeName)
.prop('enctype', 'multipart/form-data')
.prop('encoding', 'multipart/form-data')
.submit(function(e) {
options.onSubmit.apply($form[0]);
$iframe.one('load', function() {
var iframeText = $iframe.contents().find('body').text();
options.onResponse.apply($form[0], [iframeText]);
});
});
});
};
$('#input').ajaxForm({
onResponse:function(data) {
$('#output').html(data);
}
});
</script>
</body>
</html>
Your CGI code is fine. However, I highly recommend using a web framework like Pyramid or Django for your own sanity.
#!/usr/bin/python
import cgi
form = cgi.FieldStorage()
print 'Content-Type: text/html\n'
if 'uploadFile' in form and form['uploadFile'].filename:
print form['uploadFile'].value
else:
print 'no file'
$messages = $db->query("SELECT * FROM chatmessages ORDER BY datetime DESC, displayorderid DESC LIMIT 0,10");
while($message = $db->fetch_array($messages)) {
$oldmessages[] = $message['message'];
}
$oldmessages = array_reverse($oldmessages);
?>
<div id="chat">
<?php
for ($count = 0; $count < 9; $count++) {
echo $oldmessages[$count];
}
?>
<script language="javascript" type="text/javascript">
<!--
setInterval( "document.getElementById('chat').innerHTML='<NEW CONTENT OF #CHAT>'", 1000 );
-->
</script>
</div>
I'm trying to create a PHP chatroom script but I'm having a lot of trouble getting it to AutoRefresh
The content should automatically update to , how do you make it do that? I've been searching for almost an hour
I would take that PHP functionality you have and putting it in a sperate page that returns JSON. From there you can call that method using jQuery and the AJAX tools built in. Really simple. Start here for jQuery: http://api.jquery.com/category/ajax/
you'll need to set up a server side script that renders only the contents of the chat div and use ajax to grab that. it can be done with jquery quite easily:
In your html document:
<head>
...
<script src="/path/to/jquery.js" type="text/javascript"></script>
<script>
var chatUpdateInterval = null;
function initChat() {
chatUpdateInterval = window.setInterval(updateChat, 5000); /* every 5 seconds */
}
function updateChat() {
$.ajax({
url: '/url/path/to/your/script.php'
,dataType: 'HTML'
,success: function(data, status, xhr){
$('#chat').append($(data).html());
}
});
}
$(document).ready(function(){
initChat();
});
</script>
...
</head>
<body>
<div id="chat">
please stand by while we're firing up the coal!
</div>
</body>
Note that this won't be really good, it's just a sample to get you started. you should look into jquery's $.ajax