I´m trying to do this:
var http = new XMLHttpRequest();
var url = "guardarImg.php";
var params = $('#form').serialize();
http.open("POST", url, true);
http.setRequestHeader("Content-type", "multipart/form-data");
http.onreadystatechange = function() {
if(http.readyState == 4 && http.status == 200) {
alert(http.responseText);
}
}
http.send(params);
But is not working, it shows me in my php that 'Image' is not defined, but when I do it through a average Submit it works fine.
All the similar samples I saw work with string data but I need to achieve it with images to make it work later in Intel XDK
What I´m doing wrong?
Can you show me a sample?
Sorry if my question is too basic, I´m a noob with xmlhttp and ajax stuff.
You have the right idea with regard to $("#form").serialize() but for the mess that is (still) AJAX uploads. Yuck (and shame on me for not noting that detail the first time :-( ).
The problem with file uploads via AJAX is (as is often the case), Internet Explorer. Basically, it didn't support the FormData object until IE10 (which means that, if you care about supporting XP users, they'd better be running not-IE). FormData greatly simplifies the process of uploading stuff via AJAX; if you don't have that, here are your options:
Put a little tiny IFRAME on the page and manage that for the actual file upload.
Encode the form data programmatically using something like JSON and send that via jQuery.
Use a nice plugin that wraps this all for you (and uses one or more of these techniques under the covers).
I'm going to assume you don't care about IE8/9 (pretty much everyone else isn't a problem) and give you a FormData solution. Unlike the previous edit, I'm popping in the whole function in here since it's decently informative. This particular solution uploads an entire form, pulling in the existing fields into the FormData object and treating the files specially.
<!-- Many ways to skin this particular feline; I like this one :-) -->
<form onsubmit="return uploadFiles(this)">
<!-- Access from PHP using $_FILES["somefile"]["name"][$idx]... -->
<input type="file" name="somefiles" multiple="1" />
</form>
<script>
// Function to upload a form via FormData, breaking out files and cutting
// any non-named elements. Assumes that there's a #status DIV and the
// URL is hardcoded.
function uploadFiles(frm) {
var formdata = new FormData();
// I'm doing this to separate out the upload content. Note that multiple
// files can be uploaded and will appear as a decently-friendly PHP array
// in $_FILES. Note also that this does handle multiple files properly
// (a default FormData(frm) wouldn't exactly :-( ).
$(frm).find(":input").each(function(idx, ele) {
// This is a file field. Break it out.
if(ele.files) {
for(i=0; i<ele.files.length; i++) {
formdata.append(ele.name + "[" + i + "]", ele.files[i]);
}
// Not a file element, so put in the upload iff there's a name.
} else if(ele.name) {
formdata.append(ele.name, ele.value);
}
});
// Run the AJAX.
$.ajax({
url: "test.php", // Change Me :-)
type: "POST",
data: formdata,
processData: false, // Need these to keep jQuery from messing up your form
contentType: false,
success: function(data) {
$("#status").html(data);
},
error: function(xhr, status, error) {
$("#status").html("Error uploading file(s): " + error);
},
});
return false; // Keep the form from submitting
}
</script>
I have a complete HTML file and corresponding PHP that work at pastebin.
If I were you, I'd actually just use Sebastian's jQuery File Upload if you can. It's got all that modern UI goodness (include progress metering), browser abstraction, and it's MIT licensed to boot. That said, this answer will get you on your way if you just need something to copypasta. Good luck!
Related
I have a view with a generate button. When I click It I am navigating to a Generate method of a controller using ajax call.
generate = function () {
$.ajax({
url: "/franchise/Generate",
type: "POST",
data: { id: omega.franchiseInfo.Id(), imagesPath: omega.franchiseInfo.ImagesPath() },
});
}
Here is my Generate method:
public ActionResult Generate(int id, string imagesPath)
{
// some logic here
var zipFileName = #"D:\FranchiseGeneration\MyZipFile.zip";
using (var zip = new ZipFile())
{
zip.AddDirectory(#"D:\FranchiseGeneration\Test", "Generation");
zip.Save(zipFileName);
}
return File(zipFileName, "application/zip", "MyZipFile.zip");
}
MyZipFile.zip is created on my hard drive as specified. I expect the user to be prompted to download the zipped file ... but nothing happens. I am rather new to Mvc3 and I am not sure what I am doing wrong. Any suggestions with code samples are welcome. Thank You!
It's an ajax call, it doesn't make sense to return a File in an ajax call... ajax stands for Asynchronous JavaScript and XML.. ok with json ad some other text based things, but to work with binary files you'll need some exta works.
In you scenario, I think the best thing to do (the simplest one) is to perform a normal postback, not ajax (or even a simple GET would work).
It is not possible to trigger a file download via an ajax request like this.
There are other ways to make something like it happen though.
http://johnculviner.com/post/2012/03/22/Ajax-like-feature-rich-file-downloads-with-jQuery-File-Download.aspx
I'm not terribly experienced with AJAX and so am using some tools and attempting to integrate and customize them. First, this is a wordpress site using an AJAX form to submit a post. It all works great! Now, of course, I have to add a WYSIWYG editor to the mix and need to figure out how to get the html content to submit properly.
Here's the submit code:
jQuery("form.pfs").submit(function() {
// vvv I ADDED THIS LINE!!! vvv
jQuery('textarea#postcontent').val(jQuery('div.workzone iframe').contents().find('body').html());
jQuery(this).ajaxSubmit({
type: "POST",
url: jQuery(this).attr('action'),
dataType:'json',
beforeSend: function() {
jQuery('.pfs-post-form #post').val('posting...');
},
complete: function(request,textStatus,error) {
data = jQuery.parseJSON(request.responseText);
if (data && data.error) {
jQuery('#pfs-alert').addClass('error').html('<p>'+data.error+'</p>').show();
jQuery('.pfs-post-form #post').val('Post');
} else {
jQuery('form.pfs').reset();
location.reload();
}
}
});
return false;
});
As you can see, I've added that first line where I take the content of the HTML in the WYSIWYG (http://elrte.org/) and set it as the value of what would have been the original textarea (#postcontent).
The AJAX works perfectly if there's an error, so it is only the "else" portion of the routine that is throwing the error:
Uncaught SyntaxError: Unexpected token < jquery.js:2
e.extend.parseJSON jquery.js:2
jQuery.submit.jQuery.ajaxSubmit.complete pfs-script.js:31
F
So as you see, I need to validate for malicious code (not part of this help request!!) but more importantly I just want to be able to accept HTML in my form posts. Ideas? I am not 100% sure I understand what is failing and where...
turns out there was a conflict with another Plugin. tracing out the request.responseText revealed it. This code works just fine.
I'm trying to upload data captured in a local html file on an iPad and save it to server.
I found this: Sending data to an external file via Ajax
So as far as I can understand, there is no way to send the info doing something like this:
ajax.open("POST",'http://www.misite.com/canvas/testSave.php',true);
from a html on the iPad, I'm right?
So I just want to know if anyone knows a trick to do this. Thanks!
After a couple of weeks this is what I could achieved.
1.- The function that sends the data (an image generated from a canvas):
function sendImageData()
{
var filename = $("#filename").val().trim();
if(filename == ''){
alert("File name is needed");
return;
}
var uploadCanvas = $("#uploadCanvas");
var canvasData = uploadCanvas[0].toDataURL("image/png");
var debugConsole= $("#debugConsole");
debugConsole.val(canvasData);
$.ajax({
type: 'POST',
url: "http://yourremoteserver.com/canvas/save.php",
data: {
canvasData:canvasData,
filename:filename
}
}).done(function() {
alert("saved: " + filename + ".png");// THIS IS NOT WORKING YET.
}
);
}
2.- The PHP that receives and saves the data:
<?php
$imagen = $_POST['canvasData'];
$filename = $_POST['filename'];
if (isset($imagen)){
$imageData=$imagen;
$filteredData=substr($imageData, strpos($imageData, ",")+1);
$unencodedData=base64_decode($filteredData);
$fp = fopen( $filename.'.png', 'wb' );
fwrite( $fp, $unencodedData);
fclose( $fp );
}
?>
If anyone can help me with the .done function to work (remember, the html file is in an ipad and the php on a server) let me know. Cheers.
I have used Plupload for this purpose. It automagically switches between flash, silverlight, and html5 so it should work on just about any browser (including the safari on the iPad). Basically, it uploads a file to a processing script with some generated id (it generates it for you). Then, you can poll another page to get the uploaded data once it is finished uploading.
EDIT: Re-reading your post I am not sure how pertinent this is since it requires the user to select a file and I'm not sure that's what you are getting at exactly.
I tried to open a post time ago about this problem (here), thinking i was wrong making the code. Now more or less i've understood that some version of Jquery with my code doesnt work on IE7. What's Happening? I also tried to open a post on JQuery official forum (link) but no one reply. Anyway, in my old website i used to work with jquery-1.3.2.min.js , and i didnt problems. Now, i need to use the .delegate() function, so I include the jquery-1.4.2.min.js library.
Above you can see the usual code I used in my old application :
// html page
prova
// javascript page
function pmNew(mexid) {
var time = new Date;
$.ajax({
type: 'POST',
url: './folder/ajax.php',
data: 'mexid='+escape(mexid)+'&id=pmnew',
success: function(msg) {
alert(msg);
}
});
return false;
}
// asynchf.php
if($_POST['id']=="pmnew") {
echo "please, i will just print this";
}
With some suggestions by some users of this website, i edited these functions :
// html page
prova
// javascript page
function pmNew(mexid) {
var time = new Date;
$.ajax({
type: 'POST',
cache: false,
url: './folder/ajax.php' + '?dummy=' + time.getTime(),
data: 'mexid='+escape(mexid)+'&id=pmnew',
success: function(msg) {
alert(msg);
}
});
return false;
}
// asynchf.php
if($_POST['id']=="pmnew") {
echo "please, i will just print this";
}
But it STILL DOESNT WORK on IE7. Firefox, Chrome, it rocks. It works on IE7 only if i load the page, i try (and i get the error message), i reload (F5) and i retry. Or, as i said before, i change the version of Jquery :)
I loaded a testpage on a real server (so you can check yourself this problem) : click here
I hope someone can help me with this big trouble.
Cheers
The reason behind this bug is when you are using relative URLs on IE7, it actually adds your base url (or wherever your page is loaded from e.g. if you place a relative url on your home page your relative URL would actually be http://gabbatracklistworld.com/http://gabbatracklistworld.com/folder/ajax.php)
I just came across your question here on SO while searching for a solution on some same problem I had myself a few minutes ago. There's actually an article from microsoft's blog that explains how IE7 handle relative urls (which is funny because it just shows that they are proud of how their stupid browser works)
Seeing that you have no answer yet, I'd put my solution here for future reference and other devs too.
What I did is use substring() to strip the instances of my base url forcing the ajax request to use the actual relative URL.
Can you add this argument to your .Ajax options:
error:function(xhr, status, errorThrown) {
alert(errorThrown+'\n'+status+'\n'+xhr.statusText);
},
and reply with the message ?
Given so much different options to submit sth to the server, I feel a little confused.
Can someone help me to clear the idea when I should use which and why?
1> $.ajax()
2> $('#myForm').ajaxForm
3> ajaxSubmit
4> $('#myForm').submit
Thank you
I personally prefer creating a function such as submitForm(url,data) that way it can be reused.
Javascript:
function submitForm(t_url,t_data) {
$.ajax({
type: 'POST',
url: t_url,
data: t_data,
success: function(data) {
$('#responseArea').html(data);
}
});
}
HTML:
<form action='javascript: submitForm("whatever.php",$("#whatevervalue").val());' method='POST'> etc etc
edit try this then:
$('#yourForm').submit(function() {
var yourValues = {};
$.each($('#yourForm').serializeArray(), function(i, field) {
yourValues[field.name] = field.value;
});
submitForm('whatever.php',yourvalues);
});
Here is my understanding
$.ajax does the nice ajax way to send data to server without whole page reload and refresh. epically you want to refresh the segment on the page. But it has it's own limitation, it doesn't support file upload. so if you don't have any fileupload, this works OK.
$("#form").submit is the javascript way to submit the form and has same behaviour as the input with "submit" type, but you can do some nice js validation check before you submit, which means you can prevent the submit if client validation failed.
ajaxForm and ajaxSubmit basically are same and does the normal way form submit behaviour with some ajax response. The different between these two has been specified on their website, under FAQ section. I just quote it for some lazy people
What is the difference between ajaxForm and ajaxSubmit?
There are two main differences between these methods:
ajaxSubmit submits the form, ajaxForm does not. When you invoke ajaxSubmit it immediately serializes the form data and sends it to the server. When you invoke ajaxForm it adds the necessary event listeners to the form so that it can detect when the form is submitted by the user. When this occurs ajaxSubmit is called for you.
When using ajaxForm the submitted data will include the name and value of the submitting element (or its click coordinates if the submitting element is an image).
A bit late, but here's my contribution. In my experience, $.ajax is the preferred way to send an AJAX call, including forms, to the server. It has a plethora more options. In order to perform the validation which #vincent mentioned, I add a normal submit button to the form, then bind to $(document).on("submit", "#myForm", .... In that, I prevent the default submit action (e.preventDefault() assuming your event is e), do my validation, and then submit.
A simplified version of this would be as follows:
$(document).on("submit", "#login-form", function(e) {
e.preventDefault(); // don't actually submit
// show applicable progress indicators
$("#login-submit-wrapper").addClass("hide");
$("#login-progress-wrapper").removeClass("hide");
// simple validation of username to avoid extra server calls
if (!new RegExp(/^([A-Za-z0-9._-]){2,64}$/).test($("#login-username").val())) {
// if it is invalid, mark the input and revert submit progress bar
markInputInvalid($("#login-username"), "Invalid Username");
$("#login-submit-wrapper").removeClass("hide");
$("#login-progress-wrapper").addClass("hide");
return false;
}
// additional check could go here
// i like FormData as I can submit files using it. However, a standard {} Object would work
var data = new FormData();
data.append("username", $("#login-username").val());
data.append("password", $("#login-password").val()); // just some examples
data.append("captcha", grecaptcha.getResponse());
$.ajax("handler.php", {
data: data,
processData: false, // prevent weird bugs when submitting files with FormData, optional for normal forms
contentType: false,
method: "POST"
}).done(function(response) {
// do something like redirect, display success, etc
}).fail(function(response) {
var data = JSON.parse(response.responseText); // parse server error
switch (data.error_code) { // do something based on that
case 1:
markInputInvalid($("#login-username"), data.message);
return;
break;
case 2:
markInputInvalid($("#login-password"), data.message);
return;
break;
default:
alert(data.message);
return;
break;
}
}).always(function() { // ALWAYS revert the form to old state, fail or success. .always has the benefit of running, even if .fail throws an error itself (bad JSON parse?)
$("#login-submit-wrapper").removeClass("hide");
$("#login-progress-wrapper").addClass("hide");
});
});