Input::all() empty after FormData object passed - javascript

I have a form that I need to process before it's submitted. The form has several text and radio inputs, as well as a file one. I'm using jQuery to pass the form data:
$button.on('click', function(e) {
e.preventDefault();
var formData = new FormData($('.js-my-form')[0]);
$.ajax({
type: 'GET',
url: '/get-data',
data: formData,
contentType: false,
processData: false
}).done(function(response) {
// handle response
});
});
Then, in Laravel controller:
$input = Input::all() // <- EMPTY ARRAY
No idea why Input comes empty. Any help appreciated.

Your problem is that you are using a GET to send a request with enctype = multipart/form-data. When you use a native FormData object this is the format that you get by default. You can read how to send the form's data
using the POST method and setting the enctype attribute to application/x-www-form-urlencoded (default);
using the POST method and setting the enctype attribute to text/plain;
using the POST method and setting the enctype attribute to multipart/form-data;
using the GET method (in this case the enctype attribute will be ignored).
So if you set your requesto to a GET the content of your form present in the body of the request will be ignored. The enctype attribute is what tells the server how to process your request. This is why you should use POST.
Note that when you write
contentType: false,
processData: false
you are telling jQuery that do not mess with the data you are passing and leave your native Formdata object untouched. This will cause the enctype to be set automatically.

First i suggest use a type 'POST' to pass your data at your method and second, try serialize the form data
$.ajax({
type: 'POST',
url: '/get-data', /*Route laravel*/
data: formData.serialize(),
contentType: false,
processData: false
}).done(function(response) {
// handle response
});

So, I could not find any resource to confirm this, but it seems FormData won't work with GET type - at least when using jQuery's $.ajax() function.
Changed GET to POST - and the form input is getting to the Laravel controller with no problems.
Not sure I like it, thought, as I'm actually not POSTing anything, but GETting information I need. Anyways, it works.

Related

How to send file?

I want to send an image to my telegram bot via javascript (not Node.js). For this I need the token of the bot and my Telegram user ID.
Sending text messages works fine, I also succeeded in sending photos, which I gave as LINK. Now I want to take my own photos and send them directly to my bot.
This is a part of the telegram documentation:
So as I understood it, I can also send images as a file and not as a link using a post request. Unfortunately I had no great success with the implementation:
let token = "xy",
chat_id = "123"
let url = `https://api.telegram.org/bot${token}/sendPhoto?chat_id=${chat_id}`;
$("form").submit(function(e) {
let formData = new FormData(this);
e.preventDefault();
$.ajax({
url: url,
type: 'POST',
data: formData,
success: function(r) {
console.log(r);
},
error: (e) => {
console.log("Error", e)
}
return false;
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form>
<input id="fileInput" type="file" />
<input type="submit" value="submit" />
</form>
How can I implement this in pure javascript and working?
Note that https://api.telegram.org/bot${token}/sendPhoto?chat_id=${chat_id}&photo=${link_to_photo} is working.
Though it's not obvious from the jQuery documentation, you need to set two more ajax options:
processData: false
processData (default: true)
Type: Boolean By default, data passed in to the data option as an object (technically, anything other than a string) will be processed
and transformed into a query string, fitting to the default
content-type "application/x-www-form-urlencoded". If you want to send
a DOMDocument, or other non-processed data, set this option to false.
FormData should be sent unprocessed
contentType: false
contentType (default: 'application/x-www-form-urlencoded; charset=UTF-8')
Type: Boolean or String When sending data to the server, use this content type. Default is "application/x-www-form-urlencoded;
charset=UTF-8", which is fine for most cases. If you explicitly pass
in a content-type to $.ajax(), then it is always sent to the server
(even if no data is sent). As of jQuery 1.6 you can pass false to tell
jQuery to not set any content type header. Note: The W3C
XMLHttpRequest specification dictates that the charset is always
UTF-8; specifying another charset will not force the browser to change
the encoding. Note: For cross-domain requests, setting the content
type to anything other than application/x-www-form-urlencoded,
multipart/form-data, or text/plain will trigger the browser to send a
preflight OPTIONS request to the server.
$.ajax({
url: url,
type: 'POST',
data: formData,
processData: false, // TO SEND DATA UNPROCESSED
contentType: false, // TO OVERRIDE THE DEFAULT
success: function(r) {console.log(r);},
error: (e) => {console.log("Error", e)}
// return false; <-- REMOVE THIS FROM HERE
});

Trying to understand JQuery/Ajax Get/POST calls

Correct me if I'm wrong but it was my understanding that a POST was to be used if I was changing data, and a GET was to be used if I want to retrieve data.
Based on that assumption.
I have (MVC5) app.
My JavaScript
function MyLoadData(myValue) {
$.ajax({
method: 'POST',
url: '/Home/GetMyData',
contentType: 'application/json',
dataType: 'json',
data: JSON.stringify({ "MyValue": myValue}),
success: function (data) {
// Do Stuff
}
});
and my controller.
public JsonResult GetMyData(string myValue)
{ // Do Stuff }
This only works if I set the method: 'POST', if I set it to 'GET' it will still make the server call but not pass the myValue to the controller.
Also of note there is no data annotation on the GetMyData method.
In this scenario shouldn't I be using GET to get my data from the controller?
UPDATED based on comments:
function MyLoadData(myValue) {
$.ajax({
method: 'POST',
url: '/Home/GetMyData',
dataType: 'json',
data: { "MyValue": myValue},
success: function (data) {
// Do Stuff
}
});
Both POST and GET methods can pass the myValue to the controller.
GET - Requests data from a specified resource
POST - Submits data to be processed to a specified resource
GET is basically used for just getting (retrieving) some data from the server. Note: The GET method may return cached data.
POST can also be used to get some data from the server. However, the POST method NEVER caches data, and is often used to send data along with the request.
The primary difference between a GET and a POST is that the POST will also submit the form data. In your example, you can use a GET by appending ?MyValue=<myValue> to your URL and WebAPI will assign the value to the Action's parameter.
If the GET request needs to work then use this code block:
function MyLoadData(myValue) {
$.ajax({
method: 'GET',
url: '/Home/GetMyData?myValue=test',
success: function (data) {
// Do Stuff
}
});
Basically, you can use GET or POST to get the data. but in GET, the data is passed through query string. In POST it can be passed both through query string as well as body.
One real world scenario when to use POST-Suppose your method expects Customer parameter and you need to send Customer object as parameter, then you can send the json representation of Customer object through body.but its not possible through GET.
One more reason is security,if you use GET, your method can be called through browser.but if you use POST, the method can't be directly called.
These were the important difference.For more differences see this link - http://www.diffen.com/difference/GET_(HTTP)_vs_POST_(HTTP)

Jquery serialize : trying to pass a form status to an ASP.NET MVC controller without submitting the form

Working on an ASP.NET MVC application.
A form has several buttons submitting the form.
One of the buttons needs to send to the controller the form's controls status without submitting the form.
I plan to use Ajax and $('#FormID').serialize();
I wrote it this way:
function rechercher() {
var formStatus = $('#FormID').serialize();
var url = '#Url.Action("Search", "ImproItemForm"); //?'+ formStatus;
// alert('formStatus: ' + formStatus); //works fine
alert('url: ' + url);
$.ajax({
url: url,
type: 'POST',
dataType: 'json',
data:/* { improItem: formStatus },*/ formStatus ,
contentType: "application/json; charset=utf-8",
success: function (result) {
alert("success" + result);
},
error: function (result) {
alert("failure" + result);
}
});
}
My controller action is as below:
public ActionResult Search(FormCollection improItem)
{
}
If I call ajax this way, it never reaches the controller (and thus triggers the error function.
If I comment this line:
data: formStatus ,
Then it does invoke the controller method but the FormCollection improItem argument has no values of course.
So I suppose that I am not passing the data correctly to Ajax but I do not manage to get this sorted.
thx in advance.
Make sure you specify the correct content type. Right now you seem to have specified application/json; charset=utf-8 but obviously you aren't sending any JSON but rather application/x-www-form-urlencoded which is how the .serialize() method will format the form values. So just get rid of this line:
contentType: "application/json; charset=utf-8",
Usually when you are unsure about what you are sending or receiving instead of trying to explicitly specify it like you did, you'd better don't specify anything and leave jQuery figure it out. The same stands true of course for the dataType: 'json', property. If your controller action doesn't return JSON, this will cause an error. If on the other hand you don't specify the expected return type, then jQuery will simply use the Content-Type response header that the server returned and it will figure it out.
So bottom line: leave it to the framework figure it out unless you know exactly what you are doing.
Ah, and before I forget, please replace this:
public ActionResult Search(FormCollection improItem)
with:
public ActionResult Search(MyViewModel improItem)

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 set boundary while using XmlHttpRequest and FormData

I am trying to set the boundary correctly in the header while using FormData to post the XmlHttpRequest:
xhr.open("POST",url);
xhr.setRequestHeader("Content-type","multipart/form-data; boundary=...");
var formData = new FormData();
formData.append("filename", inputId.files[0]);
formData.append(...);
xhr.send(formData);
How do I get the boundary to be set in the request header here. I saw the request being set, the boundary is somehow created in the request. But the server has no idea on how to interpret it.
ES method
Simply don't set the Content-Type header manually and the browser will automatically set "multipart/form-data; boundary=..." value.
jQuery method
If you're using jQuery, set contentType option to false:
$.ajax({
url: url,
type: 'POST',
data: formData,
processData: false,
contentType: false
});
Try looking at this, How to send multipart/form-data form content by ajax (no jquery)? I am trying to work with this script with PHP as the reciever, having some problems with mixed results of warnings and I think my problem is that I have hacked away at the scripts both ends too much that its no longer functioning.
As for the comment by the other poster "If you're using JQuery", the only thing I have to say to that comment is that it is not helpful to the person not working in JQuery and JQ is not the be all and end all of scripts.

Categories

Resources