Over the last couple of days I have learnt about the canvas-element and now I want to add AJAX to save the canvas to the server. Specifically, I am letting users draw on the canvas and when they are finished they click a button and the canvas is sent and saved to the server. The code below works excellently.
Javascript:
var testCanvas = document.getElementById('imageView');
var canvasData = testCanvas.toDataURL("image/png");
var ajax = new XMLHttpRequest();
ajax.onreadystatechange=callback();
ajax.open("POST",'script.php',true);
ajax.setRequestHeader('Content-Type', 'canvas/upload');
ajax.send("canvasData"+canvasData );
function callback (){alert ('it works!');}
PHP-code:
<?php
if (isset($GLOBALS["HTTP_RAW_POST_DATA"]))
{
// Get the data
$imageData=$GLOBALS['HTTP_RAW_POST_DATA'];
$filteredData=substr($imageData, strpos($imageData, ",")+1);
$unencodedData=base64_decode($filteredData);
$fp = fopen( 'images/'.uniqid().'.png', 'wb' );
fwrite( $fp, $unencodedData);
fclose( $fp );
echo "saved";
}
else{
echo "no raw data";
}
?>
However, I would like to have the filename and location returned to the script, so that I can present the server-side image and location to the user. I have not adjusted the php-code yet, because using the following returns an empty string:
function callback () { alert (ajax.responseText);}
I have searched and the topic seems to have been addressed a couple of times without resulting in me being able to fix the above.
Where I am going wrong?
reference functions, don't call them, and wait for the readyState to return 4
var testCanvas = document.getElementById('imageView');
var canvasData = testCanvas.toDataURL("image/png");
var ajax = new XMLHttpRequest();
ajax.onreadystatechange = callback;
ajax.open("POST",'script.php',true);
ajax.setRequestHeader('Content-Type', 'canvas/upload');
ajax.send("canvasData"+canvasData );
function callback (){
if (ajax.readyState == 4) {
alert(ajax.responseText);
}
}
Related
I am really confused in using xmlhttprequest. I want to send a file to server. Is it necessary to use formdata to send the file. I am trying to send directly using xmlhttprequest. Instead of getting a file, I am getting only a text at server side.
var Stu_Image = localStorage.getItem('StuImage');
alert(Stu_Image);
nImageRequest[i] = new XMLHttpRequest();
nImageRequest[i].open("POST", "http://10.xxx.xx.xx/server/api/upload_image.php", true);
// var ImageFile = new Image();
ImageFile = "image="+Stu_Image;
nImageRequest[i].setRequestHeader("Content-type", "application/x-www-form-urlencoded");
alert(ImageFile);
nImageRequest[i].onreadystatechange = function (oEvent)
{
if (nImageRequest[i].readyState == 4)
{
alert("4 status:"+ nImageRequest[i].status+"-------"+ nImageRequest[i].statusText);
if (nImageRequest[i].status == 200)
{
alert(nImageRequest[i].responseText);
return;
}
else
{
alert("Error:"+ nImageRequest[i].statusText);
}
}
else
{
alert("Error:"+ nImageRequest[i].readyState +"----"+nImageRequest[i].statusText);
}
};
nImageRequest[i].send(ImageFile);
This is my php file
header("Access-Control-Allow-Origin: *");
$data = $_POST['image'];
//$data = $_FILES['image']['name'];
echo "".$data;
$fileData = base64_decode($data);
echo ".....".$fileData;
$uploads_dir = "server/api/uploads/";
move_uploaded_file($fileData, $uploads_dir);
if(!file_exists($fileData) || !is_uploaded_file($fileData))
{
//echo "";
echo "No upload";
}
else
{
echo "uploaded";
}
This is how I got Stu_Image
function loadImage(Value)
{
var reader = new FileReader();
reader.readAsDataURL(document.getElementById("LoadImage").files[0]);
ImgFile = document.getElementById("LoadImage").files[0];
/
// alert(ImgFile);
localStorage.setItem('StuImage',ImgFile);
alert(ImgFile);
// alert(url);
reader.onload = function (Event)
{
document.getElementById("PreviewImage").src = Event.target.result;
};
};
Okay, so after wasting a few days, I got the answer to this question. I hope the answer helps someone if he/she gets stuck here.I am not posting the code as it is very big. I was not encoding the image before sending to server.
So the right method is
1 Store Image on Canvas.
2 Encode it using canvas.toDataURL method and send using xmlhttprequest.
3 Decode it as server side. I used php function base64_decode to do it.
4 Use imagecreatefromstring() method to convert decoded string to image and then use imagejpeg() or imagepng() method to get the image.
Hope it helps someone. Happy to post code if required by anyone.
I have an XMLHttpRequest where i am sending an image across to be saved on my Amazon s3 bucket. It works correctly and the file goes to my bucket but i am getting no response back saying it is in process or has successfully uploaded. My code is below:
Javascript code in html page:
var ajax = new XMLHttpRequest();
ajax.open("POST",'http://www.xxxx.php',false);
ajax.setRequestHeader('Content-Type', 'application/upload');
ajax.send(theImage);
ajax.onreadystatechange=function(){
if (ajax.readyState==4 && ajax.status==200) {
console.log('success');
}
else {
console.log('ongoing...');
}
}
PHP code in xxxx.php:
<?php
if (isset($GLOBALS["HTTP_RAW_POST_DATA"])){
$imageData = $GLOBALS['HTTP_RAW_POST_DATA'];
$filteredData = substr($imageData, strpos($imageData, ",")+1);
$imgFileString = base64_decode($filteredData);
$s3Filename = time().'.png';
if($s3->putObjectString($imgFileString, $bucket , $s3Filename, S3::ACL_PUBLIC_READ) ){
echo "SUCCESS";
}
else{
echo "ERROR";
}
}
else {
echo "EMPTY";
}
?>
How can i get a callback to say when the upload has successfully been uploaded or if an error has occurred?
ajax.open("POST",'http://www.xxxx.php',false);
^^^^^^
You are making a synchronous request, so the request is being made and the response received before you assign your event handler. Don't do that. Remove false (or change it to true).
I have an HTML5 app that saves the canvas image to the server and then provides a link to that image that opens in a new window.
This works fine the first time I save it, but if I create and save a new image and then click on the link it displays the old image that was previously created.
Clicking on refresh will force it to display the new one, but I was wondering if there is a way to make sure it displays the correct image so that I don't have to refresh the page?
Below is what I am using to save the image.
<script>
function saveImageAs (imgOrURL) {
if (typeof imgOrURL == 'object')
imgOrURL = imgOrURL.src;
window.win = open (imgOrURL);
setTimeout('win.document.execCommand("SaveAs")', 500);
}
</script>
<script type="text/javascript">
//****************************************************************
// Save canvas content into image file. //
//****************************************************************
function saveViaAJAX()
{
document.getElementById('saveimage').style.visibility="hidden";
document.getElementById("debugFilenameConsole").innerHTML="Please wait while your image is been generated";
var testCanvas = document.getElementById('canvas');
var canvasData = testCanvas.toDataURL("image/jpg");
var postData = "canvasData="+canvasData;
var debugConsole= document.getElementById("debugConsole");
debugConsole.value=canvasData;
//alert("canvasData ="+canvasData );
var ajax = new XMLHttpRequest();
ajax.open("POST",'savecanvas.php',true);
ajax.setRequestHeader('Content-Type', 'canvas/upload');
//ajax.setRequestHeader('Content-TypeLength', postData.length);
ajax.onreadystatechange=function()
{
if (ajax.readyState == 4)
{
//alert(ajax.responseText);
// Write out the filename.
document.getElementById("debugFilenameConsole").innerHTML="Saved as <a target='_blank' href='myimage.php'> MyImage.jpg"+ajax.responseText+"</a><br>Reload this page to start a new image or click on the link above to open the file.";
}
}
ajax.send(postData);
}
</script>
And the PHP
<?php
if (isset($GLOBALS["HTTP_RAW_POST_DATA"]))
{
// 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( 'MyImage.jpg', 'wb' );
fwrite( $fp, $unencodedData);
fclose( $fp );
}
header("Content-Type: image/jpg");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("content-disposition: attachment; filename=MyImage.jpg");
imagejpeg($img, null, 100);
?>
Because you are giving the image the same name and path, the browser is helpfully caching it for you.
Use a unique path to avoid this!
You can try
var random=new Date();
var random2=getTime();
var rand=random+random2;
imgOrURL = imgOrURL.src+'?rnd='+rand
or for PHP
$rand=rand();
MyImage.php?rand=<?=$rand?>
or
$image='MyImage.php?rand='.$rand.'';
For future use, to save headache. Add dates and times first because using md5 , sha1() or a rand() or JavaScript unique key can be a nightmare, example:
/// This is much cleaner
/11.1.2012/11.05/eachier93.jpg
/11.1.2012/11.05/4358390485/93.jpg
/11.1.2012/11.10/3249203489834/234234.jpg
/// then this
/files/342748234234234/234982348394/333535.jpg
/files/4535345345/234234234234/3332.jpg
/files/23423434324/023840348234/2343.jpg
From System.Shell.itemFromFileDrop I get System.Shell.Item object item. I've tried this:
var oStream = new ActiveXObject("ADODB.Stream");
oStream.Type = 1;
oStream.Open();
oStream.LoadFromFile(item.path);
content = oStream.Read();
var thisObj = this;
var xhr = new XMLHttpRequest();
xhr.open("POST", "http://myUrl.com//");
xhr.send(content); //NOT WORKING
oStream.Close();
oStream = null;
but I really don't know what to pass in the xhr.send function.
The serverside PHP code is as simple as it could be:
if (file_exists($_FILES["file"]["name"]))
{
echo $_FILES["file"]["name"] . " already exists. ";
}
else
{
move_uploaded_file($_FILES["file"]["tmp_name"],$_FILES["file"]["name"]);
header("{$_SERVER['SERVER_PROTOCOL']} 200 OK");
header('Content-Type: text/plain');
echo "http://myUrl.com/" .$_FILES["file"]["name"];
}
any ideas what am I doing wrong ? Or any ideas about how to upload files from windows gadget at all?
This is my code where I call the Request for Ajax, than a simple input button which on onClick event send some data to a function called setValue();
This is the code (JS):
//request for ajax XML
<script type='text/javascript'>
function callAjax(){
var XMLObj = false;
if(window.XMLHttpRequest)
XMLObj = new XMLHttpRequest();
else if(window.ActiveXObject)
XMLObj = new ActiveXObject('Microsoft.XMLHTTP');
if(!XMLObj)
return false;
return XMLObj;
}
//var for ajaxobject handle;
var objAjax = callAjax();
function setValue(value, id, num, item){
if(objAjax){
if(objAjax.readyState == 4 || objAjax.readyState == 0){
objAjax.open('POST', 'addview.php', true);
objAjax.send('value=' + val + '&id='+id+'&num='+num+'&item='+item);
}
}
}
//input for sending value to function setValue();
<input type='button' onClick='setValue(1, 2, 3, 4)' />
//and this is where I handle the sent data via php
<?php
if(!$_POST['value'] || !$_POST['id'] || !$_POST['num'] || !$_POST['item'])
exit();
include('config.php');
$value = mysql_real_escape_string($_POST['value']);
$id = mysql_real_escape_string($_POST['id']);
$num = mysql_real_escape_string($_POST['num']);
$item = mysql_real_escape_string($_POST['item']);
mysql_query("UPDATE `window` SET window_val = window_val + ".$value." WHERE window_id = '".$id."' AND window_num = '".$num."' AND window_item = '".$item."' ") or die(mysql_error() );
mysql_close($con);
?>
The php script is working, I tried it with sending data manually ($_GET['']) and it's working. Also I checked the URL with alert('value='+value+'&id='+id...) and all variables are Ok, but the database won't be queried.
If you see, I don't add any function for response, reply from the server. I just only want to send those data and query the data base.
Thank you !
You may be missing
objAjax.setRequestHeader("Content-type","application/x-www-form-urlencoded");
Consider improving your function names: callAjax doesn't call Ajax, it returns a reference to the XHR object. Call it getXhr or something more like what it's actually doing.
If you're ok with jQuery, just call
function setValue(value, id, num, item){
$.post('addview.php', 'value=' + val + '&id='+id+'&num='+num+'&item='+item);
// or the cleaner version
$.post('addview.php', {value: val, id: id, num: num, item:item});
}