transform JS/HTML to web-based - problems saving click data - javascript

I made this entire experiment with html/javascript. Basically, people have to click on a chart (I used jqplot) and the console.log saves the value on the axes (var xax and yax below) they choose.
'$('#chart').bind('jqplotClick', function(event, seriesIndex, pointIndex, data) {
var xax = pointIndex.xaxis;
var yax = pointIndex.yaxis;
console.log("Coordinates according to chart location for plot1 : " + xax + " - " + yax);'
This was supposed to go on mTurk, who takes care of all the data logging. Unfortunately, non-US users are no longer allowed, so I'll have to host it on my own server (server space is no prob).
I know that I can use PHP to make a text-file on the server to save things in. What I basically need is some sort of simple way where everything that was logged with console.log in js, would now be saved by php in a text-file. I also know that PHP is server-based and Javascript is client-based, so it won't be that 'simple' I guess.
I only started coding beginning of October so I'm still a newbie. I know html/css, javascript and now some php. I read some answers on the JS-PHP relationship involving AJAX but I don't know how to apply it to my problem..

Since it looks like you're using jQuery, have a look at their ajax documentation.
But it basically boils down to sending the data you want to the server from your client-side js:
// validate the data before sending.
$.ajax({
type: "POST",
url: "saveToFile.php",
data: { xax: xax, yax : yax }
}).error(function(xhr, errStr, err) {
console.log("NO! something bad happened while sending to the server",errStr);
}).success(function(out) {
var response = JSON.parse(out);
if (response.status === 200) {
console.log(response.message);
}
else if (response.status === 500) {
console.log("data not saved, something happened while writing the file");
}
});
and handling it in your php file (this one named saveToFile.php). My php is a little rusty, sorry for any syntax errors:
<?php
// get your data from the client
$xax = $_POST['xax'];
$yax = $_POST['yax'];
$out;
// validate $xax and $yax
// save your variables to a file
$result = file_put_contents("log.txt", "Coordinates according to chart location for plot1 : " . $xax . " - " . $yax, FILE_APPEND);
// tell the user what happened
if ($result !== FALSE) {
$out = [ "message" => "success!", "status" => 200];
}
else {
$out = [ "message" => "error saving file", "status" => 500];
}
// send stuff back to the client
echo json_encode($out);
exit();
saving to file from the php docs.
This is a really basic example and doesn't check to see if the values you are sending to the server make sense, which is something you should do. Whenever sending data to the server, you should always validate on both ends; before sending it with JS AND when receiving it with PHP.
Hope that helps

Read up on jQuery, which is a pretty good starting point for making AJAX requests. You would have typically make a POST request to some PHP file on your server which then opens a file for writing and writes that output. Also make sure you look into validating cookies in PHP and make sure the data is what you want it to be, or else anyone who sends an AJAX request to your server will be able to write anything they want, and this will potentially open up your server to hackers.
When you get a little more advanced, look at setting up a database such as MySQL and using the PHP mysqli driver to store the data there, rather than in a file. Make sure you read up on how to protect your code from SQL injection.

Related

Different ways to use local variables from HTML / Javascript in PHP

Recently I have been doing a lot of work in PHP and I have become familiar with how it works. I stand by what I have said before; That every problem has an endless amount of solutions. So that is what I am after, solutions that solve the same problem.
In this case, I want variables/references to values from localstorage:
localStorage.setItem("user", "bananaflakes55");
localStorage.getItem("user");
and directly include them in PHP files. Now I have found out that using echo have a variety of uses, for example:
echo '<script type="text/javascript"> window.location.replace("' . $refclinklogin . '"); </script>';
Granted that the value there are on serverside -> client side. In this case I want similar solutions that necessarily wont require me to create a GET or POST, with HTML elements like forms, that connect these.
To sum up, I want solutions that can bring values from local and session storage, to PHP. Bring forth some funky ideas, if possible. From what I have read it is a tricky one.
Even if i understand what you want, process sould be running from PHP to client rather than the reverse.
With this in mind, a light solution can be something like that :
window.addEventListener("load", function() {
let request = new XMLHttpRequest();
request.open("POST", 'localStorageToSession.php', true);
request.onload = function () {
let saveResponse = request.responseText;
// if you want a callback or use some script return
}
let data = "jsonLocalStorage=" + JSON.stringify(window.localStorage);
request.send(data);
}) ;
Once the page is loaded, send all localStorage parsed in json to a PHP treatment (here called localStorageToSession.php).
So you can convert localstorage as $_SESSION. Something like that :
$_SESSION['jsLocalStorage'] = json_decode($_POST['jsonLocalStorage'], true) ;
Then you can use $_SESSION['jsLocalStorage'] in your backend treatments. Don't forget to add session_start() on all your files.
You can save the xml request in a function and call once localStorage is updated).
Even if that solution works, i don't recommand it if you have to deal with safety informations like passwords or user special access.

jQuery AJAX call returning 403 Forbidden error when passing Rgraph image data

I am working on a project, where I have implemented a couple of graphs/charts using the Rgraph PHP library. In my script I do the following for the graphs:
Calculate the graph points and draw the graph using the Rgraph Draw() method.
Create an image data variable using the canvas.toDataURL() method.
Pass this image data variable to the server using jQuery AJAX $.post() method.
Save the image to server via the PHP script.
Everything in this solution works great on my localhost, however on the development server, the AJAX request that passes the image data returns a 403 Error.
I logged the data on both the client and server side to determine the issue. Client side logging confirms the imageData variable being passed looks correct. However server side logging confirms that the imageData variable being passed is what is causing the issue.
There was a very similar question posted last year about this, however they were unable to determine the root cause of this. Can anyone help point me in the right direction of resolving this?
I'm thinking this is a possible data encoding issue, but if this the case, why does it work on one server and not the other?
My Relevant Javascript:
radar.Set('chart.contextmenu', [
['Get PNG', RGraph.showPNG],
null,
['Cancel', function () {}]
]);
radar.Draw();
var imageData = radar.canvas.toDataURL("image/png");
console.log('imageData: ' + imageData);
console.log('filename: ' + 'tmpRadar<?php echo $us['UsersSurvey']['user_id']; ?>-<?php echo $survey['Survey']['id']; ?>.png');
$.post("/Surveys/save_chart", {
src : imageData,
filename: 'tmpRadar<?php echo $us['UsersSurvey']['user_id']; ?>-<?php echo $survey['Survey']['id']; ?>.png'
});
Client Side Logging:
imageData: data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABLAAAAOECAYAAACxbcj6AAAgAElEQ…AgQIAAgVECAqxR49YsAQIECBAgQIAAAQIECBAgQKCfwP8CXHJ+WDHVMbcAAAAASUVORK5CYII=
filename: tmpRadar19-1.png
POST http://website.com/Surveys/save_chart 403 (Forbidden)
PHP Function called by AJAX:
public function save_chart() {
if($this->request->is('ajax')) {
$this->log('request data: '.print_r($this->request->data, true));
$filename = $this->request->data['filename'];
$src = $this->request->data['src'];
$src = substr($src, strpos($src, ",") + 1);
$decoded = base64_decode($src);
$fp = fopen(WWW_ROOT.'files/graphs/'.$filename,'wb');
if(fwrite($fp, $decoded)) {
fclose($fp);
return json_encode(array('success' => '1'));
} else {
fclose($fp);
return json_encode(array('success' => '0'));
}
}
}
Assuming CORS isn't the issue here (which it doesn't sound like it is given that it's working fine on your localhost and that it sounds like your POSTing to the same domain from which you received the original GET), it's likely a misconfiguration between Apache on your localhost and devbox. Given that the issue is only with your base 64 encoded image POST, it's likely too large so apache is rejecting it.
Per this SO post, try setting the following in either your php.ini:
post_max_size=20M
upload_max_filesize=20M
or in .htaccess / httpd.conf / virtualhost:
php_value post_max_size 20M
php_value upload_max_filesize=20M
Note that I can't tell you for sure if this is the cause until you post the apache error log.
It’s to do with mod_security (an Apache module) and the http:// part of the URL.
You have two options here,
Modify the Apache module
Client side workaround
Try removing imagedata from the form you are posting, and it should submit.
Source: 403-on-form-submit
Your use of data in .post() is a little off. If you are trying to pass a JSON object as the data for the second argument of .post(), you need to properly form it into a JSON string. Try wrapping your dictionary with JSON.stringify(). It'll take your javascript value {key1: value1, key2: value2} and format it.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify
$.post("/Surveys/save_chart", JSON.stringify(
{
src : imageData,
filename: 'tmpRadar<?php echo $us['UsersSurvey']['user_id']; ?>-<?php echo $survey['Survey']['id']; ?>.png'
}
) //end stringify
)//end post;

I'm putting my entire $_SESSION variable into a json object on page load. While this works for me, is this a good practice?

I've been doing something this at the bottom of all my views:
<script type='text/javascript'>
$.post('php/ajax.php', {type:'session'}).done(function(data){
var session = JSON.parse(data);
$(document).ready(function(){
$.getScript('resources/redactor/redactor.js');
$.getScript('javascript/year_long_calendar.js');
$.getScript('javascript/edit_lesson_modal.js');
});
});
</script>
This works really well for me. All my scripts get loaded inside of a single docReady, and all my ajax requires a token that gets generated upon login and stored in $_SESSION. This stops people from hitting my ajax logic using fake headers. By doing this, my ajax calls look something like:
$.post(url:'ajax.php', {token:session.token, id:id}).done(function(data){ ... });
I can also access other session variables
var user_id = session.user_id;
Since I've been doing this from the start of the project, I intentionally keep any sensitive information like passwords out of the session variable. What are your thoughts on this? Does any of this strike you as insecure, or terribly inefficient? I realize $.getScript is often used as a lazy way to load libraries, but I think I've found a pretty valid use for it.
None of the data in $_SESSION is sensitive except the token, and you have to be logged in to get one. Unless someone malicious hops on a machine while the real user is away and knows exactly where my ajax logic is, how it works, how I store my session, and fakes a quick header on PostMan to delete all my tables, I don't see it being an issue.
EDIT:
#AnotherGuy helped me realize a much better solution. My ajax.php file now looks like this:
<?php session_start();
include('connect.php');
include('functions.php');
// check to see if http request is ajax (easy to fake but hey might as well)
if($_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest'){
// when the user logs in, a random number is generated and saved to $_SESSION['token'].
// this block is used to pass the token to a javascript variable securely
if($_POST['type'] == 'session'){
$session = [
'token'=>$_SESSION['token'],
'user_id'=>$_SESSION['user_id']
];
echo json_encode($session);
}
// all post requests must pass the correct token variable to step into this block and access the ajax logic
if(isset($_POST['token']) && $_POST['token'] == $_SESSION['token']){
if($_POST['type'] == 'get'){
$where = null;
if(isset($_POST['where'])){
$where = json_decode($_POST['where']);
}
$order_by = null;
if(isset($_POST['order_by'])){
$order_by = json_decode($_POST['order_by']);
}
echo json_encode(get($_POST['db'], $_POST['table'], $where, $order_by)->fetchAll());
}
if($_POST['type'] == 'put'){
$set = json_decode($_POST['set']);
echo put($_POST['db'], $_POST['table'], $set);
}
if($_POST['type'] == 'update'){
$set = json_decode($_POST['set']);
$where = json_decode($_POST['where']);
update($_POST['db'], $_POST['table'], $set, $where);
}
if($_POST['type'] == 'delete'){
$where = json_decode($_POST['where']);
delete($_POST['db'], $_POST['from'], $where);
}
From how you describe you are using the session I cannot see any harm in it, but I still think it is dangerous. Imagine you in the future work on another project and then come back to this. Will you still remember not to store any sensitive information inside the session? As a basic rule of thumb is to never store sensitive information in the session unless it is the only solution, which it rarely is. But sometimes mistakes are made and they can hurt you!
I would change this to something that looks/works in the same way, but offers you more decoupling from the session. If you are fetching the entire session you are bound to retrieve some information which would never be used or should never be available to client side (through Javascript). I would create a single page that you request which can only provide the necessary information. That way you can also ensure only required information is exposed to the client side.
So instead of requesting a generic ajax.php file, I would create a page called (or something like it) userInfo.php. That way you can also eliminate the type variable you send along with it.
Hope this can help you, happy coding!
You could store that session data in browser with sesssionStorage in a serialized JSON string and manipulate it from there. Many recommend this approach over using cookies W3Schools
Cheers.

Connecting to a MySQL database using PhoneGap, AJAX, and JQuery Mobile

I'm in a team developing an Android application that will rely greatly on the use of a remote database. We are using PhoneGap and Jquery Mobile and have been attempting to connect to our MySQL database using AJAX and JSON calls. Currently, we are having trouble in our testing phase, which is to verify we even have a connection at all by pulling a hard-coded user of "Ted" from mySQL / input via MySQL Workbench.
From what we have gathered, the process of data transmission works as this:
On our html file, we have a
<script type="text/javascript" src="Connect.js"></script>
^ Which should run the Connect.js script, correct? So from there, Connect.js is ran?
Connect.js runs, connecting it to our ServerFile.php that is hosted on an external web service, allowing it to run PHP to connect to the MySQL database and pull information.
//run the following code whenever a new pseudo-page is created
$('#PAGENAME').live('pageshow', function(event)) {
// cache this page for later use (inside the AJAX function)
var $this = $(this);
// make an AJAX call to your PHP script
$.getJSON('http://www.WEBSITENAME.com/ServerFile.php', function (response) {
// create a variable to hold the parsed output from the server
var output = [];
// if the PHP script returned a success
if (response.status == 'success') {
// iterate through the response rows
for (var key in response.items) {
// add each response row to the output variable
output.push('<li>' + response.items[key] + '</li>');
}
// if the PHP script returned an error
} else {
// output an error message
output.push('<li>No Data Found</li>');
}
// append the output to the `data-role="content"` div on this page as a
// listview and trigger the `create` event on its parent to style the
// listview
$this.children('[data-role="content"]').append('<ul data-role="listview">' + output.join('') + '</ul>').trigger('create');
});
});
Here is ServerFile.php. This should connect to the MySQL Database, make the Select statement, and then send the output to the browser encoded in the JSON format.
<?php
//session_start();
$connection = mysql_connect("csmadison.dhcp.bsu.edu", "clbavender", "changeme");
$db = mysql_select_db("cs397_clbavender", $connection);
//include your database connection code
// include_once('database-connection.php');
//query your MySQL server for whatever information you want
$query = mysql_query("SELECT * FROM Users WHERE Username ='Ted'", $db) or trigger_error(mysql_error());
//create an output array
$output = array();
//if the MySQL query returned any results
if (mysql_affected_rows() > 0) {
//iterate through the results of your query
while ($row = mysql_fetch_assoc($query)) {
//add the results of your query to the output variable
$output[] = $row;
}
//send your output to the browser encoded in the JSON format
echo json_encode(array('status' => 'success', 'items' => $output));
} else {
//if no records were found in the database then output an error message encoded in the JSON format
echo json_encode(array('status' => 'error', 'items' => $output));
}
?>
Yet nothing is showing here. What do we do from here?
First thing first. Try to determine where is the problem come from, server side or client side.
Print out your database query and encoded json can be useful. If you are creating a simple API service, you should be able to enter http://www.WEBSITENAME.com/ServerFile.php using your browser and look how the output is.
Use echo to print things with php.
If all looks ok, time to print out the response you receive from the server in the javascript and see what is off.
Use console.log to print thing with javascript. The logs should appear in the logcat section of eclipse (since you are developing android app)

How to read the post request parameters using JavaScript

I am trying to read the post request parameters from my HTML. I can read the get request parameters using the following code in JavaScript.
$wnd.location.search
But it does not work for post request. Can anyone tell me how to read the post request parameter values in my HTML using JavaScript?
POST data is data that is handled server side. And Javascript is on client side. So there is no way you can read a post data using JavaScript.
A little piece of PHP to get the server to populate a JavaScript variable is quick and easy:
var my_javascript_variable = <?php echo json_encode($_POST['my_post'] ?? null) ?>;
Then just access the JavaScript variable in the normal way.
Note there is no guarantee any given data or kind of data will be posted unless you check - all input fields are suggestions, not guarantees.
JavaScript is a client-side scripting language, which means all of the code is executed on the web user's machine. The POST variables, on the other hand, go to the server and reside there. Browsers do not provide those variables to the JavaScript environment, nor should any developer expect them to magically be there.
Since the browser disallows JavaScript from accessing POST data, it's pretty much impossible to read the POST variables without an outside actor like PHP echoing the POST values into a script variable or an extension/addon that captures the POST values in transit. The GET variables are available via a workaround because they're in the URL which can be parsed by the client machine.
Use sessionStorage!
$(function(){
$('form').submit{
document.sessionStorage["form-data"] = $('this').serialize();
document.location.href = 'another-page.html';
}
});
At another-page.html:
var formData = document.sessionStorage["form-data"];
Reference link - https://developer.mozilla.org/en-US/docs/Web/API/Window/sessionStorage
Why not use localStorage or any other way to set the value that you
would like to pass?
That way you have access to it from anywhere!
By anywhere I mean within the given domain/context
If you're working with a Java / REST API, a workaround is easy. In the JSP page you can do the following:
<%
String action = request.getParameter("action");
String postData = request.getParameter("dataInput");
%>
<script>
var doAction = "<% out.print(action); %>";
var postData = "<% out.print(postData); %>";
window.alert(doAction + " " + postData);
</script>
You can read the post request parameter with jQuery-PostCapture(#ssut/jQuery-PostCapture).
PostCapture plugin is consisted of some tricks.
When you are click the submit button, the onsubmit event will be dispatched.
At the time, PostCapture will be serialize form data and save to html5 localStorage(if available) or cookie storage.
I have a simple code to make it:
In your index.php :
<input id="first_post_data" type="hidden" value="<?= $_POST['first_param']; ?>"/>
In your main.js :
let my_first_post_param = $("#first_post_data").val();
So when you will include main.js in index.php (<script type="text/javascript" src="./main.js"></script>) you could get the value of your hidden input which contains your post data.
POST is what browser sends from client(your broswer) to the web server. Post data is send to server via http headers, and it is available only at the server end or in between the path (example: a proxy server) from client (your browser) to web-server. So it cannot be handled from client side scripts like JavaScript. You need to handle it via server side scripts like CGI, PHP, Java etc. If you still need to write in JavaScript you need to have a web-server which understands and executes JavaScript in your server like Node.js
<script>
<?php
if($_POST) { // Check to make sure params have been sent via POST
foreach($_POST as $field => $value) { // Go through each POST param and output as JavaScript variable
$val = json_encode($value); // Escape value
$vars .= "var $field = $val;\n";
}
echo "<script>\n$vars</script>\n";
}
?>
</script>
Or use it to put them in an dictionary that a function could retrieve:
<script>
<?php
if($_POST) {
$vars = array();
foreach($_POST as $field => $value) {
array_push($vars,"$field:".json_encode($value)); // Push to $vars array so we can just implode() it, escape value
}
echo "<script>var post = {".implode(", ",$vars)."}</script>\n"; // Implode array, javascript will interpret as dictionary
}
?>
</script>
Then in JavaScript:
var myText = post['text'];
// Or use a function instead if you want to do stuff to it first
function Post(variable) {
// do stuff to variable before returning...
var thisVar = post[variable];
return thisVar;
}
This is just an example and shouldn't be used for any sensitive data like a password, etc. The POST method exists for a reason; to send data securely to the backend, so that would defeat the purpose.
But if you just need a bunch of non-sensitive form data to go to your next page without /page?blah=value&bleh=value&blahbleh=value in your url, this would make for a cleaner url and your JavaScript can immediately interact with your POST data.
You can 'json_encode' to first encode your post variables via PHP.
Then create a JS object (array) from the JSON encoded post variables.
Then use a JavaScript loop to manipulate those variables... Like - in this example below - to populate an HTML form form:
<script>
<?php $post_vars_json_encode = json_encode($this->input->post()); ?>
// SET POST VALUES OBJECT/ARRAY
var post_value_Arr = <?php echo $post_vars_json_encode; ?>;// creates a JS object with your post variables
console.log(post_value_Arr);
// POPULATE FIELDS BASED ON POST VALUES
for(var key in post_value_Arr){// Loop post variables array
if(document.getElementById(key)){// Field Exists
console.log("found post_value_Arr key form field = "+key);
document.getElementById(key).value = post_value_Arr[key];
}
}
</script>
function getParameterByName(name, url) {
if (!url) url = window.location.href;
name = name.replace(/[\[\]]/g, "\\$&");
var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
results = regex.exec(url);
if (!results) return null;
if (!results[2]) return '';
return decodeURIComponent(results[2].replace(/\+/g, " "));
}
var formObj = document.getElementById("pageID");
formObj.response_order_id.value = getParameterByName("name");
One option is to set a cookie in PHP.
For example: a cookie named invalid with the value of $invalid expiring in 1 day:
setcookie('invalid', $invalid, time() + 60 * 60 * 24);
Then read it back out in JS (using the JS Cookie plugin):
var invalid = Cookies.get('invalid');
if(invalid !== undefined) {
Cookies.remove('invalid');
}
You can now access the value from the invalid variable in JavaScript.
It depends of what you define as JavaScript. Nowdays we actually have JS at server side programs such as NodeJS. It is exacly the same JavaScript that you code in your browser, exept as a server language.
So you can do something like this: (Code by Casey Chu: https://stackoverflow.com/a/4310087/5698805)
var qs = require('querystring');
function (request, response) {
if (request.method == 'POST') {
var body = '';
request.on('data', function (data) {
body += data;
// Too much POST data, kill the connection!
// 1e6 === 1 * Math.pow(10, 6) === 1 * 1000000 ~~~ 1MB
if (body.length > 1e6)
request.connection.destroy();
});
request.on('end', function () {
var post = qs.parse(body);
// use post['blah'], etc.
});
}
}
And therefrom use post['key'] = newVal; etc...
POST variables are only available to the browser if that same browser sent them in the first place. If another website form submits via POST to another URL, the browser will not see the POST data come in.
SITE A: has a form submit to an external URL (site B) using POST
SITE B: will receive the visitor but with only GET variables
$(function(){
$('form').sumbit{
$('this').serialize();
}
});
In jQuery, the above code would give you the URL string with POST parameters in the URL.
It's not impossible to extract the POST parameters.
To use jQuery, you need to include the jQuery library. Use the following for that:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.1/jquery.min.js" type="text/javascript"></script>
We can collect the form params submitted using POST with using serialize concept.
Try this:
$('form').serialize();
Just enclose it alert, it displays all the parameters including hidden.
<head><script>var xxx = ${params.xxx}</script></head>
Using EL expression ${param.xxx} in <head> to get params from a post method, and make sure the js file is included after <head> so that you can handle a param like 'xxx' directly in your js file.

Categories