ajax will not send canvas data to php - php

This is the code in my js
(function(){
var video = document.getElementById('video'),
canvas = document.getElementById('canvas'),
context = canvas.getContext('2d'),
photo = document.getElementById('photo'),
vendorUrl = window.URL || window.webkitURL;
datas = canvas.toDataURL('images/png');
navigator.getMedia = navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia ||
navigator.msGetUserMedia;
navigator.getMedia({
video: true,
audio: false
}, function(stream){
video.src = vendorUrl.createObjectURL(stream);
video.play();
}, function(error){
});
document.getElementById('capture').addEventListener('click',function(){
context.drawImage(video, 0, 0, 400, 300);
photo.setAttribute('src', canvas.toDataURL('images/png'));
datas = canvas.toDataURL('images/png');
});
var canvasData = canvas.toDataURL("image/png");
var ajax = new XMLHttpRequest();
ajax.open("POST",'webcam.php',false);
ajax.setRequestHeader('Content-Type', 'application/upload');
ajax.send(canvasData);
})();
This is the php code to receive the data
<?php
if (isset($GLOBALS["HTTP_RAW_POST_DATA"]))
{
echo "true";
// Get the data
$imageData=$GLOBALS['HTTP_RAW_POST_DATA'];
// 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;
// Save file. This example uses a hard coded filename for testing,
// but a real application can specify filename in POST variable
$fp = fopen( 'test.png', 'wb' );
fwrite( $fp, $unencodedData);
fclose( $fp );
}
?>
<head>
<meta charset="UTF-8">
<Title>Document</title>
<link rel="stylesheet" href="css/main.css">
</head>
<body>
<div class="booth">
<video id = "video" width="400" height="300"></video>
Snap Shot
<canvas id="canvas" width="400" height="300"></canvas>
<img id ="photo" name = "photo" src="images/events/default.png" alt="Photo of you">
</div>
<script src="js/photo.js"></script>
</body>
<?php
?>
The application intends to take a snapshot of the user and saves the photo via javascript. I am trying to find a way to send the data back to php and utilize it to save into the database. I understand it is saved in base64 encode. I tried different methods of Ajax including the one I have saved, but the data tends to not send any data to the php folder.
Thank you in advanced.

I just suggest you to check some of you code points:
Form content type. To upload files you must use "multipart/form-data"
ajax.setRequestHeader('Content-Type', 'multipart/form-data');
You can use FormData class in JS to make form data before sending:
https://developer.mozilla.org/en/docs/Web/API/FormData/append
Canvas function "toDataURL" have no mime types "images/png". Just "image/png"

Related

I'm trying to src a js file containing XMHTTPRequest script into my HTML

If I embed my XHR file into my HTML document directly, everything works fine. As soon as I src it via
<script type="text/javascript" src="js/ajax_gallery.js">ajax_json_gallery('gallery');</script>
Nothing works, and I get no errors. I'm assuming it's something to do with the XHR being created in a separate file to the HTML. I just don't like XHR script cluttering up my HTML, I just want to load as an external JS file.
I've moved my main 3 scripts, galleryHandle.php, XHR.js, ajax_gallery.html all to the same dir level to keep things simple. And the gallery images are in a folder called "gallery", also on the same level.
Here's my code:
HTML
<html>
<head>
<title>Test</title>
<link rel="stylesheet" type="text/css" href="css/gallery.css" />
</head>
<body>
<div id="pagetop"></div>
<div id="thumbnailbox"></div>
<div id="pictureframe"></div>
<script type="text/javascript" src="XHR.js">ajax_json_gallery('gallery');</script>
</body>
</html>
JavaScript
function ajax_json_gallery(folder) {
"use strict";
var httpRequest = new XMLHttpRequest();
document.getElementById("pagetop").innerHTML = "dynamic ajax json gallery";
var thumbnailbox = document.getElementById("thumbnailbox");
httpRequest.open("POST", "galleryHandle.php", true);
httpRequest.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
httpRequest.onreadystatechange = function() {
if (httpRequest.readyState === 4 && httpRequest.status === 200) {
var data = JSON.parse(httpRequest.responseText);
var pictureframe;
pictureframe.innerHTML = "<img src='"+data.img1.src+"'>";
thumbnailbox.innerHTML = "";
for (var obj in data) {
if (data[obj].src){
thumbnailbox.innerHTML += '<div onclick="putinframe(\''+data[obj].src+'\')"><img src="'+data[obj].src+'"></div>';
}
}
}
};
httpRequest.send("folder="+folder);
thumbnailbox.innerHTML = "Loading...";
}
function putinframe(src) {
"use strict";
var pictureframe = document.getElementById("pictureframe");
pictureframe.innerHTML = '<img src = " '+src+' " >';
}
PHP
<?php
header("Content-Type: application/json");
//bring in folder name
$folder = $_POST["folder"];
//start componding json
$jsonData = '{';
//compound directory path
$dir = $folder."/";
//open directory
$dirHandle = opendir($dir);
//init while looop
$i = 0;
while ($file = readdir($dirHandle)) {
if(!is_dir($file) && strpos($file, '.jpg')){
$i++;
$src = "$dir$file";
$jsonData .= '"img'.$i.'":{ "num":"'.$i.'","src":"'.$src.'", "name":"'.$file.'" },';
}
}
closedir($dirHandle);
$jsonData = chop($jsonData, ",");
$jsonData .= '}';
echo $jsonData;
?>
I understand there are some redundancies in my code but it's just a tutorial I'm going through to learn the basics of JSON building with POST, XHR.
Anyway, help appreciated as always.
Thanks
Explanation
FROM W3C:
<script type="text/javascript" src="myscript.js">
alert('I am pointless as I won\'t be executed');
</script>
Upon meeting this element in a page, browsers will then load the file myscript.js and execute it. Any content inside the script element itself will be skipped when you provide a src attribute. The [last] example will load the file myscript.js and execute the code in it but will not execute the alert inside the script element at all.
Solution
Try the following in your head tags:
HTML
<script type="text/javascript" src="XHR.js"></script>
<script type="text/javascript">
ajax_json_gallery('gallery');
</script>
<script type="text/javascript" src="XHR.js">
You can't have src attribute and javascript both in a single tag. Separate them out. Like this...
<script type="text/javascript" src="XHR.js"></script>
<script type="text/javascript">ajax_json_gallery('gallery');</script>

PHP doesn't seem to be processing script to post to MySQL

I'm using html5 canvas to capture a signature and store it in MySQL. I've got everything in the script working except for the part that saves the signature and sends it to MySQL.
My knowledge of AJAX is none so I'm working off what I read in books, see on tutorials and get help on from here.
So in Firefox console when I click on save signature I can see the script displays the post.php file it's supposed to go to and displays a 200 ok notification but nothing happens, it doesn't post in MySQL (which doesn't surprise me as I'm sure my code is incorrect) and I don't see any errors.
What I want to accomplish is to upload the signature image to a folder on the server and save the path to the image in MySQL. Being unfamiliar with JavaScript, Jquery and Ajax I'm confused with how to get this to function.
Here is the jquery:
$(document).ready(function () {
/** Set Canvas Size **/
var canvasWidth = 400;
var canvasHeight = 75;
/** IE SUPPORT **/
var canvasDiv = document.getElementById('signaturePad');
canvas = document.createElement('canvas');
canvas.setAttribute('width', canvasWidth);
canvas.setAttribute('height', canvasHeight);
canvas.setAttribute('id', 'canvas');
canvasDiv.appendChild(canvas);
if (typeof G_vmlCanvasManager != 'undefined') {
canvas = G_vmlCanvasManager.initElement(canvas);
}
var context = canvas.getContext("2d");
var clickX = new Array();
var clickY = new Array();
var clickDrag = new Array();
var paint;
/** Redraw the Canvas **/
function redraw() {
canvas.width = canvas.width; // Clears the canvas
context.strokeStyle = "#000000";
context.lineJoin = "miter";
context.lineWidth = 2;
for (var i = 0; i < clickX.length; i++) {
context.beginPath();
if (clickDrag[i] && i) {
context.moveTo(clickX[i - 1], clickY[i - 1]);
} else {
context.moveTo(clickX[i] - 1, clickY[i]);
}
context.lineTo(clickX[i], clickY[i]);
context.closePath();
context.stroke();
}
}
/** Save Canvas **/
$("#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", 'post.php');
ajax.setRequestHeader('Content-Type', 'application/upload');
ajax.send(sigData);
// $('#debug').html(sigData);
});
/** Clear Canvas **/
$('#clearSig').click(
function clearSig() {
clickX = new Array();
clickY = new Array();
clickDrag = new Array();
context.clearRect(0, 0, canvas.width, canvas.height);
});
/**Draw when moving over Canvas **/
$('#signaturePad').mousemove(function (e) {
if (paint) {
addClick(e.pageX - this.offsetLeft, e.pageY - this.offsetTop, true);
redraw();
}
});
/**Stop Drawing on Mouseup **/
$('#signaturePad').mouseup(function (e) {
paint = false;
});
/** Starting a Click **/
function addClick(x, y, dragging) {
clickX.push(x);
clickY.push(y);
clickDrag.push(dragging);
}
$('#signaturePad').mousedown(function (e) {
var mouseX = e.pageX - this.offsetLeft;
var mouseY = e.pageY - this.offsetTop;
paint = true;
addClick(e.pageX - this.offsetLeft, e.pageY - this.offsetTop);
redraw();
});
});
and here is the PHP: Also I didn't write the php code below it's part of the entire signature pad so I'm sure it's not correct.
<?php
session_start();
if (isset($GLOBALS["HTTP_RAW_POST_DATA"]))
{
$session_id = $_SERVER['REMOTE_ADDR'];
// Get the data
$imageData=$GLOBALS['HTTP_RAW_POST_DATA'];
// 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 = "xampp/htdocs/alpha/site7/images/" . $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
$link = mysql_connect('localhost','root', 'password') OR DIE(mysql_error);
mysql_select_db("customer", $link);
mysql_query("INSERT INTO 'signature' ('session', 'image_location') VALUES ('$session_id', '$imageName')") OR DIE(mysql_error());
mysql_close($link);
}
?>
And the html:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
<title>Signature Pad</title>
<!-- The Signature Pad -->
<script type ="text/javascript" src="jquery.min.js"></script>
<script type="text/javascript" src="signature-pad.js"></script>
</head>
<body>
<center>
<fieldset style="width: 435px">
<br/>
<br/>
<div id="signaturePad" style="border: 1px solid #ccc; height: 55px; width: 400px;"></div>
<br/>
<button id="clearSig" type="button">Clear Signature</button>
<button id="saveSig" type="button">Save Signature</button>
<div id="imgData"></div>
<div
<br/>
<br/>
</fieldset>
</center>
<div id="debug"></div>
</body>
</html>
After some head beating over this I've finally been able to discover some errors.
After signing the signature pad and pressing the save signature button I get these errors in Firebug
Warning: fopen(xampp/htdocs/alpha/site6/images/sign_42281643871777767.png): failed to open stream: No such file or directory in C:\xampp\htdocs\alpha\site6\post.php on line 20
Warning: fwrite() expects parameter 1 to be resource, boolean given in C:\xampp\htdocs\alpha\site6\post.php on line 21
Warning: fclose() expects parameter 1 to be resource, boolean given in C:\xampp\htdocs\alpha\site6\post.php on line 22
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''signatures' ('session', 'image_location') VALUES ('127.0.0.1', 'sign_42281643871' at line 1
Since I don't have any knowledge of Jquery or Ajax and how they are creating the image and attempting to post it to a folder I'm pretty much stuck at this point!
seems I'm answering my own problems, I've figured out what the fopen errors were, I wasn't using an absolute path so adding a / before the start of the path cleared up everything except for the last error of this:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''signature' ('session', 'image_location') VALUES ('127.0.0.1', 'sign_11814198867' at line 1

Save canvas with an image as PNG works only in Firefox

I have an canvas on my site where the user can draw and can also add an image. By clicking a Save button I want the canvas to be saved as a PNG image.
Everything works fine in Firefox, but in Chrome for example when I add an image in the canvas and then try to save it, the image on the canvas has not been saved.
My code in javascript for adding an image is:
var imageObj = new Image();
imageObj.onload = function(){
x.drawImage(this, destX, destY, destWidth, destHeight);
};
imageObj.src = 'myImage.png';
Then for saving the canvas:
var drawingString = myDrawing.toDataURL("image/png");
var postData = "canvasData="+drawingString;
var ajax = new XMLHttpRequest();
ajax.open("POST",'save_image.php',true);
<!-- set the mime type so the image goes through as base64 -->
ajax.setRequestHeader('Content-Type', 'canvas/upload');
ajax.onreadystatechange=function() {
<!-- once the image data has been sent -->
if (ajax.readyState == 4){
alert("Saved");
}
}
ajax.send(postData);
and in PHP:
if (isset($GLOBALS["HTTP_RAW_POST_DATA"]))
{
// Get the data like you would with traditional post
$rawImage=$GLOBALS['HTTP_RAW_POST_DATA'];
// Remove the headers
$removeHeaders=substr($rawImage, strpos($rawImage, ",")+1);
// decode it from base 64 and into image data only
$decode=base64_decode($removeHeaders);
// save to your server
$imageFile = 'myImage.png';
$fopen = fopen($imageFile, 'w' );
fwrite( $fopen, $decode);
fclose( $fopen );
}
The problem is that the background canvas it is saved in both cases. Only the image on top of the background is note saved in Chrome, Safari or IE. Does anyone know why this code is behaved differently in Firefox and in other browsers?

Ajax Base64 Image Response Text

I am sending ajax request to the server as :
Client Side Code :
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Untitled Document</title>
<script language="">
if (window.XMLHttpRequest)
{
xmlhttp=new XMLHttpRequest();
}
else
{
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
var imgVal='img_id'+1;
xmlhttp.open("GET","imageprovider.php",false);
xmlhttp.send();
if(xmlhttp.readyState==4)
{
alert(xmlhttp.responseText);
document.getElementById('img').appendChild(xmlhttp.responseText);
}
</script>
</head>
<body>
<div id='img'>
</div>
</body>
And here is the server side code that shows a simple image with base64 encode.How can i get the response from client the above code and show it.
Server Side PHP Code :
<?php
$img_src = "images/1.png";
$imgbinary = fread(fopen($img_src, "r"), filesize($img_src));
$img_str = base64_encode($imgbinary);
echo '<img src="data:image/jpg;base64,'.$img_str.'" />';
?>
Try replacing
document.getElementById('img').appendChild(xmlhttp.responseText);
with
document.getElementById('img').innerHTML = xmlhttp.responseText;
Or, if you need to continue using .appendChild(), try replacing
document.getElementById('img').appendChild(xmlhttp.responseText);
with
var o = document.createElement('img');
o.src = xmlhttp.responseText;
document.getElementById('img').appendChild(o);
And replacing
echo '<img src="data:image/jpg;base64,'.$img_str.'" />';
with
echo 'data:image/jpg;base64,'.$img_str;
you capture the response
you inject the response into the DOM
Whith jQuery the code would be something like this:
$.ajax({
url: "imageprovider.php",
context: document.body,
success: function(data){
$('#objectToAddImage').html(data);
}
});
Nevertheless I would advise against passing the image as a base64 as the browser will have no way to cache it. If passing the image as a base64 encode is not an absolute requirement of your project I would recommend the server simple pass a link to the actual image.

javascript return function's data as a file

I have a function in javascript called "dumpData" which I call from a button on an html page as **onlick="dumpData(dbControl);"* What it does is return an xml file of the settings (to an alert box right now). I want to return it to the user as a file download. Is there a way to create a button when click will open a file download box and ask the user to save or open it? (sorta of like right-clicking and save target as)...
Or can it be sent to a php file and use export();? Not sure how I would send a long string like that to php and have it simple send it back as a file download.
Dennis
I don't think you can do that with javascipt, at least not with a nice solution.
Here's how to force a download of a file in PHP:
$file = "myfile.xml";
header('Content-Type: application/xml');
header("Content-Disposition: attachment; filename='$file'");
header('Content-Length: ' . filesize($file));
readfile($file);
exit;
Instead of using readfile to output your file, you could also directly display content using echo.
/EDIT: hell, someone was faster :).
EDITED:
just a proof of concept.. but you get the idea!
instead of
<a onlick="dumpData(dbControl); href="#">xml file</a>
you can have like this:
xml file
then like this:
// Assuming your js dumpData(dbControl); is doing the same thing,
// retrieve data from db!
$xml = mysql_query('SELECT * FROM xml WHERE id= $_GET['id'] ');
header("Content-type: text/xml");
echo $xml;
I eneded up going this route:
The HTML code
<script type="text/javascript">
$(document).ready(function() {
$("#save").click(function(e) { openDialog() } );
});
</script>
<button id="save" >Send for processing.</button>
The javascript code:
function openDialog() {
$("#addEditDialog").dialog("destroy");
$("#Name").val('');
$("#addEditDialog").dialog({
modal: true,
width: 600,
zIndex: 3999,
resizable: false,
buttons: {
"Done": function () {
var XMLname = $("#Name").val();
var XML = dumpXMLDocument(XMLname,geomInfo);
var filename = new Date().getTime();
$.get('sendTo.php?' + filename,{'XML':XML}, function() {
addListItem(XMLname, filename + ".XML");
});
$(this).dialog('close');
},
"Cancel": function () {
$("#Name").val('');
$(this).dialog('close');
//var XMLname = null;
}
}
});
}
PHP Code, I just decided to write the file out to a directory. Since I created the filename in the javascript and passed to PHP, I knew where it was and the filename, so I populated a side panel with a link to the file.
<?php
if(count($_GET)>0)
{
$keys = array_keys($_GET);
// first parameter is a timestamp so good enough for filename
$XMLFile = "./data/" . $keys[0] . ".kml";
echo $XMLFile;
$fh = fopen($XMLFile, 'w');
$XML = html_entity_decode($_GET["XML"]);
$XML = str_replace( '\"', '"', $XML );
fwrite($fh, $XML);
fclose($fh);
}
//echo "{'success':true}";
echo "XMLFile: ".$XMLFile;
?>
I don't know why, but when I send the XML to my php file it wrote out the contents withs escape charters on all qoutes and double quotes. So I had to do a str_replace to properly format the xml file. Anyone know why this happens?
POST the XML via a form to a php script that writes it back to the client with a Content-Disposition: attachment; filename=xxx.xml header.
<form name="xml_sender" action="i_return_what_i_was_posted.php" method="POST">
<input type="hidden" name="the_xml" value="" />
</form>
Then with js
function dumpData(arg) {
var parsedXML = ??? //whatever you do to get the xml
//assign it to the the_xml field of the form
document.forms["xml_sender"].the_xml.value = parsedXML;
//send it to the script
document.forms["xml_sender"].submit();
}
Can't remember if this loses the original window, if so, post to an iframe.

Categories