I'm helping with an open source project. It's a small Go webserver running on a device containing a Raspberry Pi. I want to be able to have a user click a button on an html screen, which calls a routine in Go, which returns 2 values, a boolean and a string.
What we are wanting to do is see which network interfaces are up on the raspberry pi e.g. is the lan connection up?
To do this I really need to ping a site from each interface. This takes a few seconds for each of 3 interfaces: Lan, WiFi, and 3G.
I can do this when the page is requested and fill in an html template as the page loads, but it means waiting maybe 10 to 15 secs for the page to load, so it seems like something is broken.
So I want to be able to list each of the 3 interfaces on the page and have the user click 'test' which then calls a routine in the underlying Go webserver.
I then need to be able to display the results from the call in a couple of text areas for each interface.
What I have tried:
I have tried registering a Go function (in this case IsLANConnectionUp) using funcmap from the net/html package and calling it from the html template from a JavaScript function, like this:
<button onclick = "getLANStatus()" class="btn btn-primary">Test</button>
<script>
function getLANStatus() {
var status = document.getElementById('status');
{{ if IsLANConnectionUp }}
status.innerHTML = "Lan is up!"
{{ else }}
status.innerHTML = "Lan is down!"
{{ end }}
}
</script>
But having the template code inside the javascript code doesn't seem to work. Also, I'd like the text output from the ping command (which my Go function getLANStatus and I don't know how to extract that data from the function call. The documentation says only one value can be returned.
Searching on StackOverflow I see this: calling Golang functions from within javascript code
$.ajax({
url: "http://www.example.com/signup",
data: {username: "whatever"} //If the request needs any data
}).done(function (data) {
// Do whatever with returned data
});
But it says things like "// Do whatever with the returned data" I'm new to web programming and so don't know how to use that code. If this is the way to go, could someone please expand on this a little?
Any help would be much appreciated.
So couple different concepts here.
Render: On the initial request to your html that generates the Test button. Your go server will render that html 1 time and return it to your browser. It does not re-request dynamically unless you wire some stuff up to make the web page change.
Client: So when someone clicks your button, the function getLANStatus will be ran. You will want that function to do a few things
Through ajax, communicate with your go server through an api that will return the status of your connections as a json object. Something like
{
"3g": "up",
"lan": "down",
"wifi": "up"
}
Second, in the done part of your ajax, you will manipulate something in the DOM in order to convey that the status of the interfaces is what it is. You could do that by finding the element, then changing the text to what is returned by the object.
As a simple first step, you can alert the payload in the function that would look like this
$.ajax({
url: "http://YOUR_GO_SERVER_IP_OR_DNS:PORT/interfaces_status.json"
}).done(function (data) {
alert(data);
console.log(data);
debugger;
});
Then if you request that with the console open in chrome, you will be able to directly play with the returned data so that you know what all it reponds to.
Related
I have a function called 'delete' like this :
<div onclick="delete($post_id, $_SESSION['id']">somelink</div>
function delete(post_id, session_id) {
var p_id = post_id;
var s_id = session_d;
$.ajax({
url:"delete.php",
type:"POST",
data: {
p_id: p_id,
s_id: s_id
},
});
})
delete.php is a page to delete the post = p_id which was added from user id = s_id.
My problem is any user can delete any post for only the console when typing in it the function 'delete();' with parameters it called and delete posts!
Any ideas, please.
You can not. Nor should you.
You should always assume that data from the client side is corrupted and should be treated accordingly. That includes form data, or in this case, a AJAX request.
This means that you have to apply validation at the server side, let PHP do it for you. E.g.: Limit the number of posts you can delete per X time. And double check that the post actually belongs to the person who is deleting it.
The reason you can't do this, is because you create javascript which is clientside. If you create a function to prevent changing the code, the client can alter the code on their machine to ignore that. You could make a function to check of the function to check is changed, but again; client can change it.
Unfortunately you can't. What you need to make sure though is making the function safe on the server which, in simple terms, boils down to
Validating every request and input parameters on the server so that people won't be able to manipulate or change server side data from client side.
make sure all data that you send to the client is originated from server as well.
one of the ways to prevent calling a function from client side is NOT to expose your methods in the global scope. and remember if your code is very critical and important, always move it to server-side. it is not a good practice to cover application design issues with programming workarounds. calling functions from client side shouldn't be an issue if the program is designed right.
First of all, this is bad. You should have authentication.
However, you can do that:
(function() {
$('#BUTTON_ID').on('click', function(post_id, session_id) {
var p_id = post_id;
var s_id = session_d;
$.ajax({
url:"delete.php",
type:"POST",
data: {
p_id: p_id,
s_id: s_id
},
});
})
})();
And add "BUTTON_ID" as id for your button.
Not that even that way, it is still not secure.
With this way, you can't call delete from the console. But someone can look into the source code and copy your ajax call and paste it into his console and it will works. It is not a good way to prevent people deleting your posts.
You should read about web application security. You should have an authentication process with tokens that expires after x time. Tokens will authenticate the user and from here, you can check if the user have the right to delete post. If the user do not have the right, you don't show the button. Then if the user call it from it console, he will get an error from the backend server.
I am writing an application that allows a user to dynamically select which columns they want to pull from our database (all public internal data) as well as customize their logic (WHERE Clause).
The result sets from these queries can be anything from a 10 records to our whole table of over 35,000 records.
On load of the result page, I trigger an AJAX function which runs the query that user has chosen and this triggers to stored procedure to run the query. This data is then passed to the AJAX success function and rendered to the DOM so it can be manipulated, exported etc.
--
The Issue:
When people choose to download the entire table (not often but certain departments have a need), we are having timeout issues which can be expected.
I am trying to find out where the bottle neck is to try and improve the experience.
When I run the query directly on the database for the 35,000 record result set, it takes about 12 seconds over VPN so I don't think the issue is with the database it self.
You can see in the image above where the timeout happened on the POST call.
I am trying to understand how the process flows for fetching / writing data to the DOM. Is the connection that is fetching the data from the database timing out or do we successfully have that data but we are timing out trying to write the 35,000 table rows?
Example Code:
var output = '';
$.ajax({
url: "api/fetchDashboardRender",
type: 'POST',
cache: false,
data: {
dashboardID: dashboardID
},
error: function(err) {
alert(err.statusText);
},
success: function(data) {
// Example .. Loop over the data in the result set
$(data).each(function(){
// Append each table row to a variable
output += '';
});
// Once done, append the variable to the DOM
$('#results').append(output);
}
});
Questions:
While I understand there is no need to write that much data to the DOM, there are reasons they want it done and I am following instruction.
Does the success function of an AJAX call include the DOM
manipulation or is it it successful once the data has been retrieved
from the source?
Is there a better way to approach this type of situation outside of making multiple calls in a paginated approach for batches of data?
Can you help me identify the main bottle neck here as to where things are being hung up?
Thanks for any pointers.
I've got a React-based app that works like this: The user makes a request for "foo", the server returns basic page info (applicable to all pages on the site), and when the client receives this (DOMContentLoaded), it does an AJAX call for the internal details "foo" and renders that.
But is it possible, if I send the data on the first request, to skip the AJAX call? (I tried this previously but was very new to React, which is how I came up with the current scheme. It's come up again because now I'm handling previously saved items.) So, I'm in my DOMContentLoaded listener, and I can see (in the Browser|Network|Response area of Chrome) all the data that has been sent by the server. It's everything I need, and it's right there, but I can't find a way to access it in Javascript.
The searches I've done have almost all turned up AJAX requests. (I am using JQuery, if that helps.) Obviously I can handle loading saved data using the same gag I'm currently using, and maybe that's a an all-around better approach.
So, once again, the question is: Is it possible to look at the response from a non-AJAX place? If it is possible, is it advisable?
Update: Let me walk through an example scenario.
The user goes to "/foo".
The server response is {:some "json"}.
In the Javascript onReady, I can do this:
console.log(window.location);
and I'll see "/foo". But can I see {:some "json"}? And how? Contrast with the AJAX call version:
The user goes to "/foo".
The server response is nothing (i.e., a 200 but no body).
The Javascript onReady has:
$.ajax({
url: "/foo/data"
type: "GET",
success: function (req) {...} //req has {:some data} in it!
So, when I make an AJAX call, I get the request. Is there any way to get that {:some data} on a non-AJAX call? This doesn't work, but I could see something like:
x = window.response();
or
x = Response.last();
Neither of those things exist, of course. I hope that clarifies what I'm looking for.
You could drop a script tag on your server-rendered page that includes a global var accessible by your script bundle. e.g.,
<script>
var myGlobalVar = { ... server data ... } <!-- // note: this is rendered raw by your server
</script>
<script src="myScriptBundle.min.js"></script>
Or, alternatively you could look into server-side rendering, which is possible with React. Check out the implementation in Redux: http://redux.js.org/docs/recipes/ServerRendering.html
i have script that works as follows:
there is main page with 'start' button that initializes javascript function which loads a php page into a div frame, then via setTimeout it calls a 'refresh' function thats supposed to work indefinitelly and refresh the page inside frame
the refreesh timer is in database and is forwarded to java like this:
var min_refresh_time = ;
$min_refresh_time_sec is taken from database earlier in the code
what i wanted to modify is so the refresh min_refresh_time would be taken each time a refresh function is run, to my surprise this worked (or at least i thought so):
var min_refresh_time = ;
(custom sql functions are defined in separate php file included in main.php which is my main page)
unfortunatelly it seems that it 'worked' only due to some strange caching on java part and my pseudo-php code to take value from database is just a hoax - it looks like it is run only initially and then stores output somehow
simplified code of what is done and what i want to do:
function refresh_code(){
refresh_time = <?php Print(sql_result(sql_execute("SELECT value FROM settings WHERE setting='min_refresh_time'", $connection), 0, 0)); ?>;
refresh_time = 5;
alert(refresh_time);
$.post("index.php",{refresh_time:refresh_time_post, account_group: "1"},
function(data)
{
$.ajaxSetup ({
cache: false,
});
$("#frame_1").html(data);
});
setTimeout(function(){refresh_code()}, refresh_time);}
lets say min_refresh_time is 1 in database, i run it, it alerts 1 then 5 each time it self-refreshes, now if i go to database and change 1 to 3 i would want it to alert 3 then 5 obvious, it still does 1 then 5 tho...
i need a way to execute a dummy php file that only takes value from database, then sends it via post back to java and it gets intercepted there, any simple way to do that?
or do i need to use entirely different method for retrieving database value without js...
thx in advance
update:
i actually came back to it and analyzed potential solutions with fresh mind
first of all, i dont think my initial code had chance to work, java cant execute serverside code by itself, i took some of my aax code from other script and reworked it to launch php file that grabs the value from database, then i intercept output data and put into variable
looks like that:
$.ajax({
method: "POST",
url: "retrieve_refresh.php",
data: { retrieve_data: "max"},
cache: false,
timeout: 5000,
async: false,
cache: false,
error: function(){
return true;
},
success: function(msg){
if (parseFloat(msg)){
return false;
}
else {
return true;
}
}
}).done(function(php_output2) {
max_refresh_time = php_output2;
});
retrieve_refresh.php returns only the variable i want but the solution is unelegant to say the least, i havent searched yet but could use a way of sending variables as post back to ajax...
I need to build a very simple button on a website that toggles a boolean on the server. When the boolean is True, I want to show a green icon, when it's False, I want to make it red. When a user clicks the icon, it should send a command to the server and update, then the icon should only change colors (image src) when the server has replied that the boolean has in fact been toggled.
I'm not very experienced with web apps, but I'm wondering what framework would work best for this? Is there an easy-to-use HTML5 way to do this? AJAX? Websocket? I'm using websockets on another page of the app and it's working, but it might be overkill for something this simple?
Websockets are complete overkill for this, however you said you have another part of the application done...what is your backend? If you like C#, ASP.NET has a lot of choices for you (MVC4 is my personal favorite).
In MVC you would create an action inside your pages controller to interpret some JSON passed from an AJAX call kind of like this:
public JsonResult FooData(int _id)
{
var dataContext = true;
if(_id == 7)
dataContext = false;
return Json(dataContext, JsonRequestBehavior.AllowGet);
}
...and on your client side you would call the FooData method like this:
$.ajax({
url: "MyController/FooData",
data: { _id: obj.id },
dataType: 'json',
async: true,
success: ChangeImage
});
Where ChangeImage is a javascript function set as your ajax calls' success callback function, so it might look like this:
function ChangeImage(data) {
if(data == true)
document.getElementById('myImg').src = "red.jpg";
else
document.getElementById('myImg').src = "green.jpg";
}
It's short, sweet and to the point. There's a learning curve but it's well worth the time and effort. I can't live without this framework anymore!
EDIT: Forgot to add data to pass in the ajax call, fixed now!
EDIT EDIT: I didn't add the logic of if click check bool -> if true, set false -> send flag -> if flag == 'change' change color -> if click ... etc etc etc because that's just busy work. This is more than enough to get you there though.
You don't want to send loads of data, or want pushing from the server, so I would recommend AJAX.
jQueries ajax is fine, but you might want to look at google if you want something more fancy.
Websockets are only usefull when you want much data, and really live.
Now you only want to send data from the client once and then, instead of keeping both sides up-to-date all the time.