I am following this post:Can't get html5 Canvas signature pad to submit to database, and is a great signature script, but I already have a error when I tried to save it into DB...the console give me this error:
Error: Failed to construct 'XMLHttpRequest': Please use the 'new' operator, this DOM object constructor cannot be called as a function.
Can you help me with this part of javascript to fix it:
$("#saveSig").click(function saveSig() {
//encode URI
var sigData = encodeURIComponent(canvas.toDataURL("image/png"));
$("#imgData").html('Thank you! Your signature was saved');
var ajax = XMLHttpRequest();
ajax.open("POST", 'sign/signature.php');
ajax.setRequestHeader('Content-Type', 'application/upload');
ajax.send(sigData);
$('#debug').html(sigData);
});
The error message says what you should do: you should use the 'new' operator to construct 'XMLHttpRequest'.
Where you create your ajax object, change var ajax = XMLHttpRequest(); to var ajax = new XMLHttpRequest();
Since you are using jquery anyway, you can use jquerys ajax method to make the ajax request instead of dealing with the browser specifics of XMLHttpRequest.
$("#saveSig").click(function saveSig() {
//encode URI
var sigData = encodeURIComponent(canvas.toDataURL("image/png"));
$.ajax({
type: "POST",
url: 'sign/signature.php',
contentType: 'application/upload',
data: sigData,
success: function () {
$("#imgData").html('Thank you! Your signature was saved');
}
});
$('#debug').html(sigData);
});
Update In response to you comments:
You must understand, that this javascript and the... click(function saveSig() {...} is executed in the browser. So you shouldn't put any php in there, because the php must be executed by the webserver. When you click on the "#saveSig" element, the browser executes this function and with the call of $.ajax(...) it sends a new HTTP POST request to the webserver in the background calling the url 'sign/signature.php'. The response data to that request is available to the success function. Here follows an example of how the webserver (php) and the browser (javascript) could work together.
sign/signature.php
<?php
// read the request data:
$sigData = (isset($_POST['data'])) ? $_POST['data'] : "";
$user_id = (isset($_POST['UserId'])) ? $_POST['userId'] : "";
// process your sigData here (e.g. save it in the database together with the user_id)
//generate the response:
echo "Successfully saved signature for user id: ".$user_id.".";
?>
javascript:
$("#saveSig").click(function saveSig() {
//encode URI
var sigData = encodeURIComponent(canvas.toDataURL("image/png"));
$.ajax({
type: "POST",
url: 'sign/signature.php',
contentType: 'application/upload',
data: {
data: sigData,
user_id: $('#user_id').val() // this get's the value from the hidden user_id input
},
success: function (responseData) {
$("#imgData").html('Thank you!' + responseData);
}
});
$('#debug').html(sigData);
});
Maybe the AJAX Introduction by w3schools is interesting to you
I already found the answer!
this is the hidden input in the canvas:
<input type="hidden" value="<?php echo $user_id; ?>" name="user_id" id="user_id" />
here is the code which will run this script:
$("#saveSig").click(function saveSig() {
//encode URI
var sigData = canvas.toDataURL("image/png");
var user_id = $("#user_id").val(); //here the id is showed, like 1, 2, etc
$("#firm").html("Thank you! Your signature was saved with the id: "+user_id);
$("#debug").html(sigData);
var ajax = new XMLHttpRequest();
ajax.open("POST", "sign/signature.php",false);
ajax.onreadystatechange = function() {
console.log(ajax.responseText);
}
ajax.setRequestHeader("Content-Type", "application/upload");
ajax.send("imgData="+sigData);
// ajax.send("user_id"+user_id); //here give me this error: InvalidStateError: Failed to execute 'send' on 'XMLHttpRequest': The object's state must be OPENED.
});
DB connection:
<?php
if (isset($GLOBALS["HTTP_RAW_POST_DATA"]))
{
$session_id = $_SERVER['REMOTE_ADDR'];
// Get the data
$imageData=$GLOBALS['HTTP_RAW_POST_DATA'];
//$user_id = (isset($_POST['user_id'])) ? $_POST['user_id'] : ""; //not works
//$user_id = $_POST['userId']; //not works
$user_id = '1'; // when I put a number the id is saved
// process your sigData here (e.g. save it in the database together with the user_id)
// Remove the headers (data:,) part.
// A real application should use them according to needs such as to check image type
$filteredData=substr($imageData, strpos($imageData, ",")+1);
// Need to decode before saving since the data we received is already base64 encoded
$unencodedData=base64_decode($filteredData);
//echo "unencodedData".$unencodedData;
$imageName = "sign_" . rand(5,1000) . rand(1, 10) . rand(10000, 150000) . rand(1500, 100000000) . ".png";
//Set the absolute path to your folder (i.e. /usr/home/your-domain/your-folder/
$filepath = "../signature/" . $imageName;
$fp = fopen("$filepath", 'wb' );
fwrite( $fp, $unencodedData);
fclose( $fp );
//Connect to a mySQL database and store the user's information so you can link to it later
include_once("CONN/configs.php");
try{
$statement = $conn->prepare("INSERT INTO SIGNATURE (`session`, `user_id`, `signature`) VALUES (?, ?, ?)");
if ($statement->execute(array($session_id, $user_id, $imageName)));
echo '<div class="alert alert-success">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
Firma con id: '.$user_id.' guardada correctamente.</div>';
}
catch (Exception $e)
{
echo '<div class="alert alert-danger">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
Error al tratar de guardar la firma.</div>';
die;
}
}
?>
I hope someone will need this.
Best regards!
Related
I'm wanting to render an image using an AJAX call but I’m having trouble returning an image from the server as a base24 string via PHP.
In the renderImage function below the test image data 'R0lGODlhCw...' is displaying correctly but the image data coming from the AJAX call is not.
I want to use AJAX instead of just outputting the image file contents into the src attribute because I eventually want to add authorization headers to the PHP file.
I think I’m missing something in the PHP file and some headers in the ajax call?
PHP file: image.php
<?php
header("Access-Control-Allow-Origin: *");
$id = $_GET["id"];
$file = '../../upload/'.$id;
$type = pathinfo($file, PATHINFO_EXTENSION);
$data = file_get_contents($file);
$base64 = 'data:image/' . $type . ';base64,' . base64_encode($data);
return $base64;
?>
JS
function renderImage(id) {
//return "R0lGODlhCwALAIAAAAAA3pn/ZiH5BAEAAAEALAAAAAALAAsAAAIUhA+hkcuO4lmNVindo7qyrIXiGBYAOw==";
return $.ajax({
url: '[server URL]/image.php',
data:{"id":id},
type: 'GET',
});
};
$('.feedImage').each(async function() {
try {
const res = await renderImage($(this).data("id"));
$(this).attr("src","data:image/gif;base64," + res);
} catch(err) {
console.log("error"+err);
}
});
raw image obtained from How to display an image that we received through Ajax call?
First you should fix your php image rendering
<?php
header("Access-Control-Allow-Origin: *");
$id = $_GET["id"];
$file = '../../upload/'.$id;
$type = pathinfo($file, PATHINFO_EXTENSION);
$data = file_get_contents($file);
$base64 = 'data:image/' . $type . ';base64,' . base64_encode($data);
echo json_encode(array('id' => $base64));
?>
Then your javascript, as you already defined the data image type there is no need to repeat it on the javascript.
function renderImage(id) {
//return "R0lGODlhCwALAIAAAAAA3pn/ZiH5BAEAAAEALAAAAAALAAsAAAIUhA+hkcuO4lmNVindo7qyrIXiGBYAOw==";
return $.ajax({
url: '[server URL]/image.php',
data:{"id":id},
type: 'GET',
});
};
$('.feedImage').each(async function() {
try {
const res = await renderImage($(this).data("id"));
$(this).attr("src", res);
} catch(err) {
console.log("error"+err);
}
});
I am trying to search for all properties in a database that are in one suburb. I have read that it has something to do with the HTML code 204 but I still do not undertand what to do or what it really means. I have not done any JS or PHP in a while so this may be a really silly error but I cannot for the life of me figure it out. Please Help!
Here is my JS code:
function basicSearch(){
//Connect Script to the PHP
var urlLink = "basicSearch.php";
//Get search parameters:
var searchAreaBar = document.getElementById("searchAreaBar").value;
//define the parameters to send to php
var strParameters = "searchAreaBar="+searchAreaBar + "&sid=" + Math.random();
// define the options for the AJAX request
var objOptions = {
// use method post
method: "post",
// use strParameters as the parameters
parameters: strParameters,
// if successfil call fuction(objXHR)
onSuccess: function(objXHR) {
// if objXHR. responseText = yes
if(objXHR.responseText=='Yes'){
alert("Success!");
}
else{
alert("Error! No Properties Found!");
}
}
}
// define the AJAX request object
var objRequest = new Ajax.Request(urlLink,objOptions);
}
Here is my PHP code:
<?php
//Link the username and password:
$connect = mysqli_connect("localhost", "admin", "12345", "realestate") or die ('Connection to database failed: ' . mysql_error());
//Extract variables for request parameters:
extract($_REQUEST);
//Define the query:
$BasicSearch = "SELECT * FROM properties WHERE Suberb='$searchAreaBar'";
//Run the query:
$resDasicSearch = mysqli_query($BasicSearch) or die(mysql_error());
//SET intCount to number of rows in result:
$intCount = mysqli_num_rows($resDasicSearch);
//If intCount is greater than 0:
if($intCount > 0){
//Echo Yes:
echo "Yes";
}
else{
//Echo no:
echo "No";
}
?>
Thanks in advance.
The error was that the browser's compiler was "commenting out" all the php and adding empty HTML tags. It was then getting confused as there was an "empty" document.
This was because the website (including JS, PHP and HTML files) were being stored and run from a local directory. For example:
the URL read:
file:///C:/xampp/htdocs/"Project Name"/Index.html
the correct URL is:
localhost/"Project Name"
IF you are using XAMPP, the folder containing all your project files need to be placed in the htdocs folder in the xampp directory.
As you seem to be using an Ajax function that is not shown it is hard to determine the root cause of the problem because nothing above, as far as I can tell, would yield the error you allude to in the title of the posting - namely "XML Parsing Error: no root element found" - I wonder therefore if there should be a configuration option in Ajax.Request that needs to be set to deal with a basic string response?
That aside you might be able to make use of the following - perhaps even for diagnosis purposes.
<?php
/*
---------------
basicSearch.php
---------------
*/
$dbhost = 'localhost';
$dbuser = 'admin';
$dbpwd = '12345';
$dbname = 'realestate';
$db = new mysqli( $dbhost, $dbuser, $dbpwd, $dbname );
$sql='select * from `properties` where `suberb`=?';
$stmt=$db->prepare( $sql );
if( $stmt ){
$searcharea = $_POST['searchAreaBar'];
$stmt->bind_param( 's', $searcharea );
$stmt->execute();
$stmt->store_result();
$stmt->bind_result( $suberbs );
$stmt->fetch();
echo $stmt->num_rows()==0 ? "No" : "Yes";
}
$stmt->close();
$db->close();
?>
<script>
/* reuseable utility ajax function */
function ajax( method, url, params, callback, options ){
var xhr=new XMLHttpRequest();
xhr.onreadystatechange=function(){
if( xhr.readyState==4 && xhr.status==200 )callback.call( this, xhr.response, options, xhr.getAllResponseHeaders() );
};
var async=params.hasOwnProperty('async') ? params.async : true;
var query=[];
for( var n in params )query.push(n+'='+params[n]);
switch( method.toLowerCase() ){
case 'post': query=query.join('&'); break;
case 'get': url+='?'+query.join('&'); params=null; break;
}
xhr.open( method.toUpperCase(), url, async );
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
xhr.send( params );
}
/* function that does the search */
function function basicSearch(){
/* configure the parameters to be used in the ajax request */
var method='post';
var url='basicSearch.php';
var params={
searchAreaBar:document.getElementById('searchAreaBar').value,
sid:Math.random()
};
var callback=function(r,o,h){
alert( r ? 'Success' : 'Error! No Properties Found!' )
}
var options={};
/* call the ajax function */
ajax.call(this,method, url, params, callback, options);
}
</script>
Today I meet this error in Firefox's console, that is so simple, while all my API return JSON, one of my API return text/html and it causes Firefox show up that error!
I have changed my NodeJS Express code:
res.end('');
To
res.json({});
ANd it is okay now! Hope it can help someone!
Basically my program is a web page with 5 radio buttons to select from. I want my web app to be able to change the picture below the buttons every time a different button is selected.
My problem is coming in the JSON decoding stage after receiving the JSON back from my php scrip that accesses the data in mysql.
Here is my code for my ajax.js file:
$('#selection').change(function() {
var selected_value = $("input[name='kobegreat']:checked").val();
$.ajax( {
url: "kobegreat.php",
data: {"name": selected_value},
type: "GET",
dataType: "json",
success: function(json) {
var $imgEl = $("img");
if( $imgEl.length === 0) {
$imgEl = $(document.createElement("img"));
$imgEl.insertAfter('h3');
$imgEl.attr("width", "300px");
$imgEl.attr("alt", "kobepic");
}
var link = json.link + ".jpg";
$imgEl.attr('src', link);
alert("AJAX was a success");
},
cache: false
});
});
And my php file:
<?php
$db_user = 'test';
$db_pass = 'test1';
if($_SERVER['REQUEST_METHOD'] == "GET") {
$value = filter_input(INPUT_GET, "name");
}
try {
$conn = new PDO('mysql: host=localhost; dbname=kobe', $db_user, $db_pass);
$conn->setAttribute(PDO:: ATTR_ERRMODE, PDO:: ERRMODE_EXCEPTION);
$stmt = $conn->prepare('SELECT * FROM greatshots WHERE name = :name');
do_search($stmt, $value);
} catch (PDOException $e) {
echo 'ERROR', $e->getMessage();
}
function do_search ($stmt, $name) {
$stmt->execute(['name'=>$name]);
if($row = $stmt->fetch()) {
$return = $row;
echo json_encode($return);
} else {
echo '<p>No match found</p>;
}
}
?>
Here's my HTML code where I am trying to post the image to.
<h2>Select a Great Kobe Moment.</h2>
<form id="selection" method="get">
<input type="radio" name="kobegreat" value="kobe1" checked/>Kobe1
<input type="radio" name="kobegreat" value="kobe2"/>Kobe2
<input type="radio" name="kobegreat" value="kobe3"/>Kobe3
</form>
<div id="target">
<h3>Great Kobe Moment!</h3>
</div>
And here's is what my database looks like:
greatshots(name, link)
name link
------ --------
kobe1 images/kobe1
kobe2 images/kobe2
kobe3 images/kobe3
Whenever I run the web app right now, the rest of the images on the page disappear and the image I am trying to display won't show up. I get the alert that "AJAX was a success" though, but nothing comes of it other than the alert. Not sure where I am going wrong with this and any help would be awesome.
As mentioned you should parse the JSON response using JSON.parse(json);.
Also, you should specifically target the div element with a simpler setup:
$("#target").append('<img width="300px" src="' + link + '.png"/>');
I use the following Ajax request to pass data:
var query = {
"username" : $('#username').val(),
"email" : $('#email').val(),
}
$.ajax({
type : "POST",
url : "system/process_registration.php",
data : query,
cache : false,
success : function(html) {
// output
}
});
My php-file (process-registration.php), in which the query is being processed, looks like this:
require_once 'db.php';
$username = $_REQUEST['username'];
$email = $_REQUEST['email'];
// Include new user into database
$db -> query("INSERT INTO users (username, email) VALUES ('$username', '$email');");
//Identify user id of this new user (maybe there is a faster way???)
$results = $db -> query("SELECT * FROM users WHERE username='$username'");
while ($result = $results->fetch_assoc()) {
$user_id = $result['id'];
}
// My output?
Now comes my question: How can I tell the Ajax command / the PHP script to return as a result two elements:
a HTML message: <p>You have registered successfully</p>
the $user_id that I have identified via the loop above
I need the user_id, because in the frontend I want to include it as a GET parameter into the href of the button "Go to admin area" that will appear AFTER the Ajax request will be completed.
Try this:
$response = array('user_id'=>$user_id,'message'=>'Success - user created');
echo json_encode($response);
This will give return a json object that you can access in JS.
$.ajax({
type : "POST",
url : "system/process_registration.php",
data : query,
cache : false,
dataType: 'json',
success : function(html) {
// output - do something with the response
console.log(html.user_id);
console.log(html.message);
}
});
I think it would be better to change the array in string by putting a special character(I use % or #)between different values. In your case just echo 'You have registered successfully%'.$user_id ;. Now explode the response string and use both.
I have a jQuery script file on a page which requires data to be uploaded. Depending on if the data uploaded has a value or not, the PHP page will either return the current time (if value uploaded !isset()), or some sql data. However, when the variable I upload actually has a value, it still returns the !isset() method. Am I doing something incorrectly?
AJAX
$.ajax({
url: 'download.php',
type: 'REQUEST',
datatype: 'json',
data: ({
last_downloaded: latestTimestamp,
username: username
}),
success: function (data) {
parsedData = $.parseJSON(data);
if (!latestTimestamp) {
latestTimestamp = parsedData.most_recent;
}
}
});
}
if latestTimestamp is null, (it should be the first time this method is run), then the most recent time is run. However when it runs the second time, latestTimestamp has a value when I console.log.
PHP
<?php
// Get variables sent
$last_chat_time = $_REQUEST['last_downloaded'];
$username = $_REQUEST['username'];
// Start echoing JSON
if (!isset($last_chat_time)) {
// User did not send last chat time they have, assume they just joined
// Get the most recent chat date
$SQL = 'SELECT current_timestamp() as "most_recent" from dual';
$results = mysql_fetch_assoc(mysql_query($SQL));
$last_chat_time = $results;
echo '{"most_recent":"' . $results['most_recent'] . '"}';
}
else{
$SQL = 'return some tasty data'
$result = mysql_query($SQL);
$messages = Array();
while ( $row = mysql_fetch_assoc($result) ) {
$messages[] = Array(
'chat' => $row['chat'],
'time' => $row['time_sent'],
'username' => $row['username']
);
}
echo json_encode($messages);
}
On the php, it ALWAYS returns the first if. However, if I visit the url directly for the php page and append ?last_downloaded=somedate, it returns the correct information. Am I doing the AJAX incorrectly?
To me this has to be updated to type : 'post or get' because php's $_REQUEST handles both, so you can change your type to this:
$.ajax({
url: 'download.php',
type: 'post',
or this:
$.ajax({
url: 'download.php',
type: 'get',