base64 code send to server by java script, ajax - javascript

I am using Html5, Java script, ajax and java. I am uploading a image from desktop to the crop and after the crop it is showing in bootstrap modal in same page. But i am not getting URL for this Image, I am getting some Base64 code and when i am sending this base64 code than it is not working.
I seen this post but i did not get any solution from this link:
https://stackoverflow.com/
This code for static image, Showing first time.
My code:
HTML:
<div class="img-container">
<img src="../assets/img/picture.jpg" alt="Picture">
</div>
<div class="modal fade docs-cropped" id="getCroppedCanvasModal" aria-hidden="true" aria-labelledby="getCroppedCanvasTitle" role="dialog" tabindex="-1">
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<a class="btn btn-primary" id="download" download="cropped.png" href="javascript:void(0);">Upload</a>
</div>
</div>
Java script Code:
(function () {
var $image = $('.img-container > img');
var $download = $('#download');
$('#getCroppedCanvasModal').modal().find('.modal-body').html(result);
if (!$download.hasClass('disabled')) {
$download.attr('href', result.toDataURL());
//console.log("*****************"+result.toDataURL());
var swapUrl = result.toDataURL();
console.log("*******" + swapUrl);
// document.getElementById('replaceMe').src = swapUrl;
$('#download').click(function () {
var b = result.toDataURL();
$.ajax({
url: "/sf/p/customizeText",
type: 'GET',
data: b,
success: function (response) {
console.log("999999999999999999999999999999999----------------" + b)
},
complete: function (response) {
},
error: function (response) {
}
});
});
}
}
I am assign result.toDataURL() into variable b. But it is showing some base64 code.
How i am send this image to server.
I am giving one snippet.
Please give me some idea achieve to this solution.

Hi you can check this solution also
Javascript code
var base64before = document.querySelector('img').src;
var base64 = base64before.replace(/^data:image\/(png|jpg);base64,/, "");
var httpPost = new XMLHttpRequest();
var path = "your url";
var data = JSON.stringify(base64);
httpPost.open("POST", path, false);
// Set the content type of the request to json since that's what's being sent
httpPost.setRequestHeader('Content-Type', 'application/json');
httpPost.send(data);
This is my Java code.
public void saveImage(InputStream imageStream){
InputStream inStream = imageStream;
try {
String dataString = convertStreamToString(inStream);
byte[] imageBytes = javax.xml.bind.DatatypeConverter.parseBase64Binary(dataString);
BufferedImage image = ImageIO.read(new ByteArrayInputStream(imageBytes));
// write the image to a file
File outputfile = new File("/Users/paul/Desktop/testkey/myImage.png");
ImageIO.write(image, "png", outputfile);
}catch(Exception e) {
System.out.println(e.getStackTrace());
}
}
static String convertStreamToString(java.io.InputStream is) {
java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
return s.hasNext() ? s.next() : "";
}

Related

How to send a cropped image in formData to PHP

I have a form with several inputs. One input is a file uploader. I'm using Cropperjs. That is working fine. It produces a base64 img. I want to be able to pass this cropped preview image to a php page for processing along with other post variables as ajax formData. I'm able to pass the other $_POST variables via the submit button in php. How do I get the image to pass it?
To me it seems to not be appending to the formData or I am not asking for the right FILES var...
https://jsfiddle.net/nick1572/c6027thL/6/
HTML
<div class="modal fade" id="modal" tabindex="-1" role="dialog" aria-labelledby="modalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="modalLabel">Crop the image</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<div class="img-container">
<img id="image" src="https://avatars0.githubusercontent.com/u/3456749">
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-primary" id="crop">Crop</button>
</div>
</div>
</div>
</div>
<!--end modal-->
<div class="file_drop_zone">
<div class="preview">
<img id="preview_image" accept="image/*"><!-- this is the image that needs to be passed.-->
</div><!--end preview-->
<div class="file__controls">
<label for="file_input">
<i class="fa fa-upload download_icon"></i><br>
<span class="drag__files_or">Drag File in or</span>
<span class="choose__file_btn">Choose File</span>
<input type="file" name="file" id="file_input">
</label>
</div>
</div><!--End file_uploader-->
JS
// Set the vars
var drop_zone = document.querySelector('.file_drop_zone');
var input = document.getElementById('file_input');
var image = document.getElementById('image');
var preview_image = document.getElementById('preview_image');
var preview_wrapper = document.querySelector('.preview');
var $modal = $('#modal');
var cropper;
var $submit = $('.seminar_form_submit');
var $event_form = $('.seminar_event_form');
// Create a function to read the file upload
// provided by the user.
function readFile(event) {
var url;
// File passed to FileList
var file = event.target;
// create a variable to pass in the the url.
// In this case it is the reader result. Then
// show the bootstrap modal.
var done = function (url) {
input.value = '';
image.src = url;
$modal.modal('show');
};
// Create a new File Reader instance
// for getting the result
var reader = new FileReader();
reader.onload = function() {
done(reader.result);
};
// If the event type is a 'change' then grab the
// file otherwise if the file is a 'drop'
// we get the file through the dataTransfer
if (event.type === 'change') {
reader.readAsDataURL(file.files[0]);
console.log(file.files[0]);
} else if (event.type === 'drop') {
reader.readAsDataURL(event.dataTransfer.files[0]);
}
}
// Once the modal is shown, create a new cropper instance and
// assign it to the #image div. // Once the modal is hidden
// destroy the instance for resetting cropper.
$modal.on('shown.bs.modal', function () {
/* global Cropper */
cropper = new Cropper(image, {
aspectRatio: 1,
viewMode: 0,
zoomable: true,
cropBoxMovable: true,
minContainerWidth: 100,
minContainerHeight: 100,
autoCropArea: 0.5
});
}).on('hidden.bs.modal', function () {
cropper.destroy();
cropper = null;
});
// Add listener to the crop button on the modal. If there is a cropper
// instance then set the canvas to the getCroppedCanvas function
// provided by cropperjs. We can set the dims there. We want to set the initial
// preview image src to the canvas. This is now a string in the form of
// a base64. Then hide the modal.
var crop = document.getElementById('crop');
var canvas;
var initialPreviewURL;
crop.addEventListener('click', function (crop) {
canvas = cropper.getCroppedCanvas({
width: 180,
height: 180,
fillColor: '#fff',
imageSmoothingEnabled: false,
imageSmoothingQuality: 'high'
});
initialPreviewURL = preview_image.src;
preview_image.src = canvas.toDataURL();
preview_wrapper.style.display = 'block';
$modal.modal('hide');
});
$event_form.on('submit', function(e) {
e.stopPropagation();
e.preventDefault();
var form_data = new FormData(document.getElementById('my_form'));
canvas.toBlob(function(blob) {
form_data.append('preview_image', blob);
for (var key of form_data.entries()) {
console.log(key);
}
});
$.ajax({
url: 'create_event.php',
data: form_data,
cache: false,
processData: false,
contentType: false,
type: 'POST',
success: function() {
console.log('success');
},
error: function () {
preview_image.src = initialPreviewURL;
},
complete: function () {
console.log('completed');
}
});
});
I am able to see the output in the console. By using a for loop on the entries
["preview_image", File]
If I error_log on the php. The output only shows 'error here' it does not show the preview_image
error_log("error here");
error_log($_FILES['preview_image']);
Here is the output from the Network > Response tab on the php page.
var_dump($_POST); or var_dump($_FILES);
array(9) {
["subject"]=>
string(12) "Persons Name"
["details"]=>
string(39) "Designer and wanna be web developer...."
["event-title"]=>
string(21) "This is another title"
["location"]=>
string(58) "This place"
["aux"]=>
string(13) "George Carlin"
["start-date"]=>
string(10) "2019-10-18"
["start-time"]=>
string(5) "08:00"
["end-date"]=>
string(10) "2019-10-18"
["end-time"]=>
string(5) "09:00"
}
array(1) {
["file"]=>
array(5) {
["name"]=>
string(0) ""
["type"]=>
string(0) ""
["tmp_name"]=>
string(0) ""
["error"]=>
int(4)
["size"]=>
int(0)
}
thanks!!
Well after digging around for a few days I went with just adding a hidden field and setting that value as the base64 string. I already had a ton of PHP error handling scripts already so I removed the ajax call. Now, the base64 string gets passed along with the POST array.

Upload file with text using AJAX & ASP.NET

I am having trouble uploading a file and value from a textbox/textarea in a single AJAX post. The entire project was created with AJAX posts to send data and receive resulting html/data. This means every button is handled with javascript/jquery and not asp.net's default onClick. Searches online yield answers with file upload but none of them show or explain any way to pass other parameters/data along with it.
*EDIT - I am not receiving any specific errors or crash attempting this. I try to run the file upload code in the success of the note upload or vice versa. It doesn't seem to be able to run both even if I switch it to asynchronous. I am more trying to get ONE single AJAX post to send both the file and the note to be handled in one codebehind function.
*EDIT(due to duplicate flag) - This is ASP.NET, not php. Please fully read questions before jumping to duplicate/closed conclusions.
Below is code/example of what I have so far.
HTML :
<div id="Modal_New_Document" class="modal fade" role="dialog">
<div class="modal-dialog Modal-Wrapper">
<div class="modal-content">
<div class="modal-header Modal-Header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h3 class="modal-title">Upload New Document</h3>
</div>
<div class="modal-body Modal-Body">
<table>
<tr>
<th>Document :</th>
<td>
<input type="file" id="FileUpload_Modal_Document" />
</td>
</tr>
<tr>
<th>Note :</th>
<td>
<textarea id="TextArea_Modal_Document_Note" style="width: 400px;"></textarea>
</td>
</tr>
</table>
</div>
<div class="modal-footer Modal-Footer">
<button type="button" class="btn btn-success" onclick="enterDocumentInfo()">Upload</button>
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
This is the most important part. I prefer to upload using the $.Ajax such as the example below. I was able to get only the file upload to work with the submitDocument()
Javascript :
function submitDocument()
{
var fileUpload = $("#FileUpload_Modal_Document").get(0);
var files = fileUpload.files;
var data = new FormData();
for (var i = 0; i < files.length; i++) {
data.append(files[i].name, files[i]);
}
var options = {};
options.url = "FileUploadHandler.ashx";
options.type = "POST";
options.data = data;
options.contentType = false;
options.processData = false;
options.success = function (result) { alert("Gud"); };
options.error = function (err) { alert(err.statusText); };
$.ajax(options);
}
$.ajax({
type: "POST",
url: "Lease_View.aspx/enterDocument",
data: JSON.stringify({
leaseID: leaseID,
userID: userID,
note: note
}),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function ()
{
// Gud
},
error: function ()
{
// Bad
}
});
Codebehind FileUpload
public class FileUploadHandler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
if (context.Request.Files.Count > 0)
{
HttpFileCollection files = context.Request.Files;
for (int i = 0; i < files.Count; i++)
{
HttpPostedFile file = files[i];
// Upload code here
}
}
context.Response.ContentType = "text/plain";
context.Response.Write("File(s) Uploaded Successfully!");
}
public bool IsReusable
{
get
{
return false;
}
}
}
WebMethod Codebehind
I prefer to be able to upload file through this instead of above.
[System.Web.Services.WebMethod]
public static void enterDocument(string leaseID, string userID, string note)
{
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnString"].ConnectionString);
SqlCommand cmd;
cmd = new SqlCommand("INSERT INTO Lease_Documents " +
"(File_Name) " +
"VALUES " +
"(#File_Name)", conn);
cmd.Parameters.AddWithValue("#File_Name", note);
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();
}
I figured it out. Basically how to pass additional parameters is using data.append(name, value) in the javascript. You can receive the value in the .ashx handler by using (HttpContext)context.Request.Form["name"]. Unfortunately it is using the handler instead of the webmethod, but at least it works.
In Javascript
var data = new FormData();
for (var i = 0; i < files.length; i++) {
data.append(files[i].name, files[i]);
}
data.append("Note", note);
In Codebehind
string note = context.Request.Form["Note"].ToString();

Encoding large images into base64 doesn't work

I'm using a simple form that posts an image to my server in the form of a base64 string. When I upload small images (< 500 kb) it works perfectly for .jpg and .png files. But when the size is for example 4 mb the function does nothing, doesn't even print the alert:
HTML:
<form action="/nuevo_cuadro" method="post" accept-charset="utf-8">
<input id="foto" type="file" name="foto" />
<button type="submit" class="btn btn-primary" onclick="encodeImageFileAsURL();">Upload</button>
</form>
JS:
function encodeImageFileAsURL() {
var filesSelected = document.getElementById("foto").files;
var filename = document.getElementById("foto").value;
var regex = /.*\\(.*)/;
var match = regex.exec(filename);
filename = match[1];
if (filesSelected.length > 0) {
var fileToLoad = filesSelected[0];
var fileReader = new FileReader();
fileReader.onload = function(fileLoadedEvent) {
var srcData = fileLoadedEvent.target.result; // <--- data: base64
alert(srcData);
$.ajax({
type: 'POST',
url: '/upload/' + filename,
data: srcData,
dataType: "text",
contentType:"text/plain"
});
}
fileReader.readAsDataURL(fileToLoad);
}
}
Are you deliberately trying to do two HTTP POST operations? You've got <input type="submit"> so as soon as the JS function returns the HTTP form POST is performed and you're off. If you change to <input type="button"> then the post doesn't get performed by the form and you should be able to start debugging.
Also, I'm not sure what's going to happen when you try to alert out a base64 encoded image that's a few megabytes big!
I had success by paring down your example to this:
function encodeImageFileAsURL() {
var filesSelected = document.getElementById("foto").files;
var file = filesSelected[0];
var reader = new FileReader();
reader.onload = (function (f) {
return function (e) {
alert('***got here***');
};
})(file);
reader.readAsDataURL(file);
}
With the button changed to type button, not submit.

Prevent blank page on bad file download

In our Angular JS application, I am downloading a file by simply calling window.location.
HTML:
<div class="row">
<div class="col-md-3 col-sm-4 col-xs-6" ng-repeat="file in files">
<div class="well well-sm truncate">
<a href="" title="Download {{file.FileName}}" ng-click="download(file)" ><b>{{file.FileName}}</b></a><br />
<small>{{(file.FileSize/1024)|number:2}} KB</small><br />
<i class="fa fa-trash CP text-danger pull-right" ng-show="mUser.Role>=20" title="Delete file" ng-click="deletefiles(file.AttID)"></i>
<small>Uploaded by {{file.AddedByName}} on {{file.Created|date:'dd MMM yyyy'}}</small>
</div>
</div>
</div>
Angular method:
$scope.download = function (ff) {
if (confirm('Download this file?')) window.location = "api/files/download?token=" + $rootScope.token + "&IDKey=" + ff.IDKey;
}
Web API Controller Method:
[HttpGet]
public HttpResponseMessage download(string Token, string IDKey)
{
HttpResponseMessage lResponse = new HttpResponseMessage(HttpStatusCode.OK);
// Validate request
Result lRes = UserClass.GetUserByToken(Token);
if (!lRes.IsSuccess)
{
lResponse.Content = new StringContent("User Token is invalid");
lResponse.StatusCode = HttpStatusCode.Forbidden;
return lResponse;
}
// Get File object
AttClass lAtt = AttClass.GetFile(IDKey);
if (!lAtt.IsOk)
{
lResponse.Content = new StringContent("Attachment ID Key is invalid");
lResponse.StatusCode = HttpStatusCode.NotFound;
return lResponse;
}
// Return file
lResponse.Content = new StreamContent(new FileStream(lAtt.GetFullPath(), FileMode.Open, FileAccess.Read));
lResponse.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") { FileName = lAtt.FileName };
lResponse.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
return lResponse;
}
The file download works very well when Token and IDKey is valid. However, in other cases, the user is shown a blank page with a simple error message. Can I prevent this and just display an alert on the original page with the reason why the download failed?
PS: I do not want to use the HTML5 SaveAs functionality or filesaver.js.
you can try this
1- Did you try downloading file using iframe instead of the using
window.location
document.getElementById("myiframe").src="api/files/download?token=" + $rootScope.token + "&IDKey=" + ff.IDKey;
and the check the iframe body
document.getElementById('myiframe').contentDocument.body.innerHTML
Re EDIT
document.getElementById("myiframe").src="your url";
document.getElementById("myiframe").addEventListener("load",
function(){
console.log(this.contentDocument.contentType);
if(!(document.getElementById("myiframe").contentDocument.contentType=="application/octet-stream"))
alert("Downlaod Failed");
else
alert("Thank you for downloading");
});
Its very dificult to handle server response when you are using window.location.
You can use ajax call in angularJs to download or you can check your response too.
$http({
url: 'server/url',
method: "POST",
responseType: 'arraybuffer'
}).success(function (data, status, headers, config) {
//check your response here
//smaple code for excel download
var blob = new Blob([data], {type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"});
var objectUrl = URL.createObjectURL(blob);
var anchor = angular.element('<a/>');
anchor.attr({
href: objectUrl,
target: '_blank',
download: fileName + '_' + new Date().getTime() + '.xlsx'
})[0].click();
}).error(function (data, status, headers, config) {
});
`

AJAX Show Image after Upload

i working on uploading files using ajax for almost 3 hours and successfully managed to make it work, please check the code:
View
<div class="form-horizontal">
<div class="form-group">
#Html.Label("Choose Image(s)", new { #class = "control-label col-sm-3" })
<div class="col-sm-5">
<input type="file" name="UploadFile" id="UploadFile" accept=".png, .jpg, .gif" multiple />
</div>
</div>
<div class="form-group">
<div class="col-sm-5 col-sm-offset-3">
<input type="button" value="Save" id="save" class="add btn btn-primary" />
<div style="color:red">
#ViewBag.error
</div>
</div>
</div>
</div>
<div style="margin-top: 17px;">
#foreach (var item in Model.Content)
{
<div class="gallery">
<a href="#item.ImagePath" title="#item.Description" data-gallery>
<img src="#item.ThumbPath" alt="#item.Description" class="img-rounded" style="margin-bottom:7px;" />
</a>
<input type="button" class="delete btn btn-danger" value="Delete" data-picid="#item.PhotoId" />
</div>
}
</div>
Controller
[HttpPost]
public ActionResult Create(Photo photo)
{
var model = new Photo();
foreach (string file in Request.Files)
{
var fileContent = Request.Files[file];
if (fileContent.ContentLength == 0) continue;
model.Description = photo.Description;
var fileName = Guid.NewGuid().ToString();
var extension = System.IO.Path.GetExtension(fileContent.FileName).ToLower();
using (var img = System.Drawing.Image.FromStream(fileContent.InputStream))
{
model.ThumbPath = String.Format(#"/GalleryImages/thumbs/{0}{1}", fileName, extension);
model.ImagePath = String.Format(#"/GalleryImages/{0}{1}", fileName, extension);
// Save thumbnail size image, 100 x 100
SaveToFolder(img, fileName, extension, new Size(200, 200), model.ThumbPath);
// Save large size image, 800 x 800
SaveToFolder(img, fileName, extension, new Size(600, 600), model.ImagePath);
}
// Save record to database
model.CreatedOn = DateTime.Now;
db.Photos.Add(model);
db.SaveChanges();
}
return Json("File Uploaded Successfully");
}
JQuery/AJAX
<script type="text/javascript">
$('#UploadFile').on('change', function (e) {
var $this = $(this);
var files = e.target.files;
if (files.length > 0) {
if (window.FormData !== undefined) {
var data = new FormData();
for (var x = 0; x < files.length; x++) {
data.append("file" + x, files[x]);
}
$.ajax({
type: "POST",
url: '/Home/Create',
contentType: false,
processData: false,
data: data,
success: function (result) {
console.log(result);
//add code to refresh the gallery with the new uploaded image
},
error: function (xhr, status, p3, p4) {
var err = "Error " + " " + status + " " + p3 + " p4;
if (xhr.responseText && xhr.responseText[0] == "{")
err = JSON.parse(xhr.responseText).Message;
console.log(err);
}
});
} else {
alert("Error! This browser does not support file upload, please change your browser");
}
}
});
</script>
SavetoFolder
private void SaveToFolder(Image img, string fileName, string extension, Size newSize, string pathToSave)
{
// Get new image resolution
Size imgSize = NewImageSize(img.Size, newSize);
using (System.Drawing.Image newImg = new Bitmap(img, imgSize.Width, imgSize.Height))
{
newImg.Save(Server.MapPath(pathToSave), img.RawFormat);
}
}
NewImageSize
public Size NewImageSize(Size imageSize, Size newSize)
{
Size finalSize;
double tempval;
if (imageSize.Height > newSize.Height || imageSize.Width > newSize.Width)
{
if (imageSize.Height > imageSize.Width)
tempval = newSize.Height / (imageSize.Height * 1.0);
else
tempval = newSize.Width / (imageSize.Width * 1.0);
finalSize = new Size((int)(tempval * imageSize.Width), (int)(tempval * imageSize.Height));
}
else
finalSize = imageSize; // image is already small size
return finalSize;
}
but the problem is i have to refresh the browser to see the added image, what should i put in ajax on sucess upload to add the image dynamically without refreshing browser?
Since you are having option to upload multiple images I would suggest to go with below approach:
your controller now would look like:
[HttpPost]
public ActionResult Create(Photo photo)
{
List<Photo> model = new List<Photo>();
//create list of photo model
foreach (string file in Request.Files)
{
var fileContent = Request.Files[file];
if (fileContent.ContentLength == 0) continue;
var fileName = Guid.NewGuid().ToString();
var extension = System.IO.Path.GetExtension(fileContent.FileName).ToLower();
string thumpath,imagepath = "";
using (var img = System.Drawing.Image.FromStream(fileContent.InputStream))
{
model.Add(new Photo(){
Description=photo.Description,
ThumbPath = String.Format(#"/GalleryImages/thumbs/{0}{1}", fileName, extension),
ImagePath = String.Format(#"/GalleryImages/{0}{1}", fileName, extension),
CreatedOn=DateTime.Now
});
//fill each detail of model here
thumpath = String.Format(#"/GalleryImages/thumbs/{0}{1}", fileName, extension);
//separate variables to send it to SaveToFolder Method
imagepath = String.Format(#"/GalleryImages/{0}{1}", fileName, extension);
SaveToFolder(img, fileName, extension, new Size(200, 200), thumpath);
SaveToFolder(img, fileName, extension, new Size(600, 600), imagepath);
}
}
foreach(var md in model)
{
//loop again for each content in model
db.Photos.Add(md);
db.SaveChanges();
}
return Json(new {model=model },JsonRequestBehavior.AllowGet);
//return the model here
}
in ajax success you can create the image with the model returned values as below:
success: function (result) {
var model = result.model;
$(model).each(function (key,value) {
$('<img />').attr({
src: value.ThumbPath
}).appendTo("body");
//note you can append it to anywhere, like inside container or something
})
}
I would set the src attribute of the img tag usign jQuery in your success function:
success: function (result) {
$("img").attr('src' , '/path/to/your/img');
},
If you don't know the public path to your image on client side you can use the response object:
return Json("{ path : "+model.ImagePath+"."+fileName+"."+extension+"}");
There is a few possibilities, which to use depends on pictures size etc.
Personaly I (if images are not too big) would on server side convert image ot base64 and return it with ajax and display the data returned from server, of course it would need conversion as well.
Check out this article, i think i'll help you :)
Base64 encoded image

Categories