JS: FormData w/ File Input is Crashing Ajax Request - javascript

Got a really odd problem that didn't show up until I pushed my code to a live server and tried to use it with my iPhone.
This is submitting to a node.js script that I've set to log all incoming request (along with headers and methods) and the logs show nothing being received when the problem below presents itself.
So anyway:
$('#addrecord').on('submit', function(e) {
e.preventDefault();
var url = '/admin/app/addrecord'
var data = $('#addrecord')[0];
var formData = new FormData(data);
$.ajax({ // create an AJAX call...
data: formData,
processData: false,
contentType: false,
cache: false,
type: "POST", // GET or POST
url: url, // the file to call
success: function(response) { // on success..
if (response.name == 200) {
if (response.message == "add") {addComplete(response.address);}
else {editComplete(response.address);};
}
else {
console.log("Form Rejected");
}
},
error: function(response) {
console.log("Error - " + JSON.stringify(response));
}
});
});
This is paired with the usual <form id="addrecord" method="post" enctype="multipart/form-data" role="form"> ... </form> in my html file.
So the problem is that is this form I have an <input type="file" id="photo" name="photo"> input field. If I try to submit the form without an image selected in this input, the form doesn't send anything and just hangs. Absolutely nothing is received by the server (remember, I'm logging every request).
Now, if I use the file input to select an image off my phone, or if I edit the html to remove the input file field, the Ajax request fires without a hitch and everything is received perfectly by my node.js server.
I'm really stumped on this one. Any ideas?

Apparently, this is a bug in Safari.
Ended up detecting if a file had been selected, and if not, deleting the element from the DOM before submitting the form.

Related

jQuery AJAX fail with files in form request

I have an issue with jQuery AJAX call on my Laravel application. It fails when using type="file" in the form.
I can't reproduce the issue locally, it happens on prod server only.
$.ajax({
url: url,
type: $(this).attr("method"),
dataType: "JSON",
data: new FormData(this),
processData: false,
contentType: false,
...
The error I get is:
POST ... net::ERR_CONNECTION_CLOSED
No errors in Laravel logs, if I dump error in error callback there is only a message "error", so nothing helpful there.
What might be the issue?
For some reason the server freaks out if you set file type and try to submit a form without actually submitting the actual file. In that case the field comes up as having name "" and size 0.
Doing this worked like a charm:
var verifyIdentity = formData.get('verify_identity')
if(verifyIdentity && verifyIdentity.size === 0){
formData.delete('verify_identity')
}

I can't understand AJAX calls for the life of me [duplicate]

This question already has answers here:
What is AJAX, really?
(21 answers)
Closed 5 years ago.
Ok, pardon the dramatic title, but making AJAX calls has to be the most confusing thing to do for me in my coding journey so far.
I’m completing a project where a user enters a keyword into a search bar and results are returned using the Wikipedia API. I’ve watched several tutorials on making AJAX calls and gone over the documentation, but it’s just not clicking.
The main questions that go on in my head when trying to figure this out:
What the heck is supposed to go into an AJAX call and how do I find out? I've gone over the documentation and know that there are a number of settings that can be specified in an AJAX call, but how do I figure out what settings I need to use? What do these settings mean?!
I know this might be a stupid question to most, but I'm just starting out and want to learn!
This is honestly all I have and currently understand:
$(function() {
// make ajax request
$.ajax({
url: "https://en.wikipedia.org/w/api.php", // this is the API endpoint
dataType: json;
});
});
What is an AJAX request?
Ajax is a set of web development techniques using many web
technologies on the client side to create asynchronous web
applications.
With Ajax, web applications can send data to and retrieve from a
server asynchronously (in the background) without interfering with the
display and behavior of the existing page.
Think of an AJAX request the same way you would think about an HTTP request. You are simply requesting files, text, or any other resource that is located on a server.
Why should I use AJAX requests?
They provide benefits to user experience, functionality, and performance.
For example, let's say you are trying to build a text-messaging application. To build something like this, you will need to have the new text messages appear on the page without the user needing to do something. This is called: Dynamically loaded content.
This can be achieved with AJAX.
How can I make an AJAX request?
By using jQuery, a framework for Javascript, we can make the experience alot easier. Here's a basic AJAX request with jQuery AJAX.
$.ajax({ *properties* });
The AJAX method takes some properties:
URL: The source you want to pull information from.
Method: The request method you want to use. (POST, GET, PULL)
Data: The data you wish to send to the source.
There's a lot more, however for simplicity reasons I am only going to name those.
Let's say you want to create a login system without a page refresh. This is really simple!
First, we need to setup the backend.
if (isset($_POST['username']) && isset($_POST['password'])) {
$username = $_POST['username'];
$password = $_POST['password'];
if ($username == 'USER' && $password == 'PASS') {
echo('success');
} else {
echo('failure');
}
}
Save this inside a file called login.php.
Second, let's setup the frontend.
<form method="POST" action="login.php">
<input name="username" type="text" placeholder="Username">
<input name="password" type="password" placeholder="Password">
</form>
We now have a foundation for an ÀJAX request. Before I implement it, let's talk about what the PHP and HTML are doing.
The HTML has a form, which has two inputs, username and password. As we can see from the attributes, the form will send the data to login.php using the POST method. The PHP will check if they're set, and if they're correct.
Unfortunately, this setup causes one of the most hated website features. THE REFRESH.
How can we solve this? AJAX Baby!
First, remove the attributes on the form.
<form>
<input name="username" type="text" placeholder="Username">
<input name="password" type="password" placeholder="Password">
</form>
Second, add a submit event listener.
$('form').submit(function(event) {
});
Third, add a preventDefault() on the event to stop the page refresh.
$('form').submit(function(event) {
event.preventDefault();
});
Fourth, get the form values.
$('form').submit(function(event) {
event.preventDefault();
var $form = $(this);
var username = $form.find('input[name="username"]').val();
var password = $form.find('input[name="password"]').val();
});
Fifth, add the AJAX.
$('form').submit(function(event) {
event.preventDefault();
var $form = $(this);
var username = $form.find('input[name="username"]').val();
var password = $form.find('input[name="password"]').val();
$.ajax({
url: 'login.php',
method: 'post',
data: { username: username, password: password },
success: function(response) {
alert(response);
}
});
});
This will send the data to the login.php file on form submission. If the values are set, the PHP will echo (or give the data to AJAX) the status. It will return success or failure depending on the username and password accuracy.
Hope this helped! It took forever.
Ok, I'm not an "Ajax master" but here is an example of how you can use it, I hope it will help you.
Imagine you have a simple log in form in HTML :
<form method="POST" name="connexion" id="connexion">
<input type='text' id='add_url' name="add_url" required/>
<label for="add_url">Add URL</label>
<input type="submit" name="sub_add" value="Add">
</form>
Now I have a.js file where I want to check if the value added is good and I want to show a result if it's okay, but I don't want to reload my page. So I will make an Ajax call :
function add_url () {
var data = $('input[name = "add_url"]').val(); // Here I select my input "add_url" and put the value on my var "data"
$.ajax({
type: "POST", // How I want to send my data on my php page
url: "mypage.php" // the name of the file where I will use this data
data: {"add" : data}, // The data I will use in my php, with the name "add"
dataType: "json", // The type of data I want to receive
success: function(response) {
// If my ajax call worked, I will do some code here
},
error: function (xhr, status, msg) {
// If my ajax call failed, I want to know why so I will use "xhr, status and msg" to have some information about why it failed
}
});
}
Now in my php, I will use the data send with ajax and build a JSON response :
// mypage.php
<?php
$url = $_POST['add']; // I put the data send in my var $url
// you do some code here with your data, for example I add the new URL in some array and the new array is $data
$result['status'] = "success"; // All is ok so I say it
$result['message'] = "All is ok !" // I add some message
$result['data'] = $data; // The data I will use in my JS
$result = json_encode($result); // I need a JSON as response, remember?
echo $result; // My response
?>
Now in my ajax function, if all is ok I can use what I send in the success part:
success: function(response) {
if (response.status === "success") { // I test if the status I send is "success"
alert(response.message); // The message I send
console.log(response.data); // I want to see in my console the data I receive
}
}
This is just an example, but I hope you have a better idea of how to use it :)
It is hard to answer this question here and write about the use of all configuration of AJAX. I would suggest you to learn about HTTP Request in general. How it works and what all headers are there and their use. There is this nice tutorial on HTTP requests and AJAX . Please look into https://code.tutsplus.com/tutorials/a-beginners-guide-to-http-and-rest--net-1634 . Keep on using and exploring the AJAX calls. You will learn it with the time.
This question is closed so I hope other newbies who are learning about ajax
and are not looking for jQuery solution will get some idea from this page.
Asynchronous Javascript And XML (AJAX) is something that runs without stopping your entire code execution (in short, AJAX is asynchronous).
In normal JavaScript, codes are executed synchronously. This means that one code cannot be executed before the codes before it have been executed.
However, in AJAX, the codes after ajax code are still executed, even though the ajax code has not finished executing.
jQuery's $.ajax method is basically the over-simplified JavaScript below:
function ajax(settings){
var ajax = new XMLHttpRequest(), // initializing AJAX constructor
header = 'application/x-www-form-urlencoded';
ajax.addEventListener('readystatechange', function(e){
if (this.readyState == 4){ // if request is ready
if (this.status == 200) // if request is successful
settings.success(this); // run `success` function
else // if request is unsuccessful
settings.fail(this); // run `fail` function
}
});
if (settings.dataType === 'json') header = 'application/json';
ajax.open(settings.type, settings.url, settings.async); // opens connection with the server
ajax.setRequestHeader('Content-Type', header); // sets ajax request header
ajax.send(settings.data); // sends data to server
}
ajax({
type: 'POST',
url: 'api.php',
dataType: 'json',
data: {},
async: true,
success: function(e){
alert('Ajax successful');
},
fail: function(e){
alert('Ajax failed');
}
});
The code above explains what AJAX is. The code below explains what asynchronous mean.
If ajax is set to be synchronous:
var a = 0;
a += 1;
ajax({
type: 'POST',
url: 'api.php',
dataType: 'json',
data: {},
async: false, // async is set to false
success: function(e){
a += 10;
console.log(a);
},
fail: function(e){
alert('Ajax failed');
}
});
a += 2;
console.log(a);
After a few seconds (because of awaiting server's response), the console will log two 13 in the console. This is because the a += 2 will only be executed after the ajax()'s execution has ended.
However, if ajax is set to be asynchronous:
var a = 0;
a += 1;
ajax({
type: 'POST',
url: 'api.php',
dataType: 'json',
data: {},
async: true, // async is set to true
success: function(e){
a += 10;
console.log(a);
},
fail: function(e){
alert('Ajax failed');
}
});
a += 2;
console.log(a);
The console will immediately first log 3, then after a few seconds, logs 13. This is because while the ajax() is waiting for the server's response, the a += 2 and the codes behind are still being executed, even though the ajax() is still executing (waiting for server's response). Once the server responds, it will then only execute the a += 10 and the other console.log(a).
Of course, to make meaningful ajax request, you will need some code at the server side.
Assuming we have a fake api from api.php:
if (isset($_POST['hello']) && isset($_POST['foo'])){
$array = [
'one' => $_POST['hello'],
'two' => $_POST['foo'];
];
}
echo json_encode($array);
Then in JavaScript:
ajax({
type: 'POST',
data: {
hello: 'world',
foo: 'bar',
},
success: function(response){
console.log(response);
},
});
The console will then log something similar to the following:
{
'one': 'world',
'two': 'bar',
}

How can I send an object to the server on form submit without ajax?

I have an application that is written on the top of ASP.NET MVC 5 framework. For one page, I am using this awesome jQuery-QueryBuilder plugin to let the user create filters to narrow down the results of the dataset.
When the user submits the form "by clicking the submit button" I want to call a function builder.queryBuilder('getRules') provided by jQuery-QueryBuilder which returns and object that needs to be sent to the server. I don't want the request to be sent as string. Also I don't want to sent it as ajax request.
Here is what I have done. The following code is not working. When the server receives the request the rules are always null.
$('#submit-form').click(function (event) {
event.preventDefault();
var btn = $(this);
var rules = builder.queryBuilder('getRules');
if (!$.isEmptyObject(rules)) {
$('#QueryBuilder_Rules').val(rules);
btn.closest('form').submit();
}
});
I tried to use AJAX to send the post request to the server like the code below shows. The code below worked fine. However, I don't want to use AJAX, I want to do the same thing using regular form post request
$('#submit-form').click(function (event) {
event.preventDefault();
var btn = $(this);
var rules = builder.queryBuilder('getRules');
if (!$.isEmptyObject(rules)) {
$.ajax({
type: "POST",
url: url,
data: {Rules: rules}
});
}
});
How can I correctly send the rules object as an object not a string to the server using standard post request?
What is the problem in using Ajax?
You may consider doing the following:
$.ajax({
type: "POST",
url: url,
data: JSON.stringify({Rules: rules}),
dataType: "json",
contentType: "application/json",
success: function (json) {
}
[HTTPPost]
public void Rules(YourClass[] array){...}

Jquery ajax returning 404 not found

I'm using Ajax to pass my form data and files to a PHP file for processing.
Javascript:
$("form#applyform").submit(function(){
var data = new FormData();
jQuery.each($('#file')[0].files, function(i, file) {
data.append('file-'+i, file);
});
$.ajax({
url: 'ValidateApplication.php',
data: data,
cache: false,
contentType: false,
processData: false,
type: 'POST',
success: function(data){
alert(data);
}
});
}
ValidateApplication.php definitely exists. I can view it if I type in the address into the web browser, however when I submit the form chrome console returns 404.
The PHP is in the same folder as the HTML page the JavaScript is running on so I am confused as to why I keep getting a 404.
UPDATE
Changing POST to GET gets rid of the 404 error, but returns a 500 Internal Server Error
UPDATE 2
Changing the action of the form to ="ValidateApplication.php" and submitting it as normal (without AJAX) leads to the correct file without any errors.
I've had the same issue and after 2 hours looking for what was causing the 404 Not Found error I found that I was recently playing with the header() from PHP and had forgotten to delete the following line of code:
header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found");
After deleting it, my Ajax functions became normal again.
It seemed to be a problem with the FormData object. Once I changed my method to use .serialize() instead, the page worked just fine.
$("form#applyform").submit(function(){
var data = $("form#applyform").serialize();
jQuery.each($('#file')[0].files, function(i, file) {
data.append('file-'+i, file);
});
$.ajax({
url: 'ValidateApplication.php',
data: data,
cache: false,
contentType: false,
processData: false,
type: 'POST',
success: function(data){
alert(data);
}
});
}
For me, it was that I used an input field with name="name" which made the called page return a 404. Weird stuff, hope this helps someone.
Try adding a / before the filename:
url: '/ValidateApplication.php',
Try changing the request type from POST to GET and see if it works.
Try commenting out parts of the code:
/*cache: false,
contentType: false,
processData: false,*/
Try another browser.
Please validate you have provided name="" attribute properly in the form
Form submit validate all bean attribute from name attribute of the input
Please check your PHP page name!
Do not use page-ajax.php, but instead use page_ajax.php.
Based on my case, I'd be sure to recheck your url address.

How to catch JSON result from ASP.NET MVC 4 Controller?

I'm trying to catch data from the AJAX POST, which I've sent via jQuery to controller endpoint of ASP.NET MVC, like this:
$("form#auth").submit(function() {
var login = $('input[id=login]').val();
var password = $('input[id=password]').val();
$.ajax({
url: "/Home/Auth",
type: "POST",
data: "Login=" + login + "&Password=" + password,
dataType: 'json',
contentType: 'application/json; charset=utf-8'
success: function() {
}
});
I've tested the controller understads what I'm sending to him, but the main problem is with the returning the result for my jQuery function.
I'm returning the result from Controller like this:
http://ideone.com/hNkF3Z
But I don't understand why the server is returning a file for download:
If to open the file, the result is valid: {"Result":"failed"}
I know, that I didn't write a code in a success function in JavaScript, but I think server must not return a file download and also the debugger must stop at the breakpoint, which was defined on last scope } of success function.
What you're seeing is the default form submission. Because you don't prevent the default browser action, the form is still being posted as if the event handler wasn't even there.
Update your JavaScript to prevent the default browser behavior with e.preventDefault()
$("form#auth").submit(function(e) {
e.preventDefault();
/* rest of your code here. */
}

Categories

Resources