Laravel - AJAX file upload returning null - ajax

This is my ajax request:
var files = $('#imgur_attach')[0].files;
if(files.length > 0){
var fd = new FormData();
// Append data
fd.append('file',files[0]);
fd.append('_token',$globalToken);
$.ajax({
type: "POST",
dataType: "json",
contentType: false,
processData: false,
url: host + "/attach-comment-image/" ,
data: {fd},
Controller:
public function attach(Request $request) {
$this->validate($request, [
'file' => 'image|required',
]);
When sending this ajax request, the validator tells me that the "file" field is required. Trying to return request->get('file') returns null.
However, when I do console.log(fd); before the ajax request, it returns the following:
Why is this happening? I don't normally upload files with AJAX over a regular POST request, so I don't understand what I'm missing.

Try stringify data before sending like this:
$.ajax({
...
data: {fd: JSON.stringify(fd),
...

you need to add multipart form data
contentType: "multipart/form-data",

Wrapping the input around with a form tag like this did the trick:
<form method="POST" enctype="multipart/form-data">
Not sure why setting contentType: "multipart/form-data" in the ajax request doesn't work, but this solution works so I'll just use this instead.

Related

Ajax link does not send POST request

I have the following ajax link:
#Html.AjaxActionLink(item.Name, "https://test.testspace.space/storage/Data/stream?tokenValue=e58367c8-ec11-4c19-995a-f37ad236e0d2&fileId=2693&position=0", new AjaxOptions { HttpMethod = "POST" })
However, although it is set to POST, it seems that it still sends GET request.
UPDATE:
As suggested below, I also tried with js functuion like this:
function DownloadAsset() {
alert("downloading");
$.ajax({
type: "POST",
url: 'https://test.testspace.space/storage/Data/stream?tokenValue=add899c5-7851-4416-9b06-4587528a72db&fileId=2693&position=0',
success: function () {
}
});
}
However, it still seems to be GET request. Parameters must be passed as query and not in the body of the request because they are expected like that by the target action. I don't know why (it would be more natural to have GET request) but back-end developer designed it like this due to some security reason.
If I use razor form like this, then it works:
<html>
<form action="https://test.testspace.space/storage/Data/stream?tokenValue=2ec3d6d8-bb77-4c16-bb81-eab324e0d29a&fileId=2693&position=0" method="POST">
<div>
<button>Send my greetings</button>
</div>
</form>
</html>
However, I can not use this because I already have bigger outer form on the page and I'll end up with nested forms which is not allowed by razor/asp.
The only way is to use javascript but for some reason it does not make POST request.
#Html.AjaxActionLink will generate to <a> tag,and tag will only have HttpGet request method.If you want to send HttpPost with <a> tag,you can use it call a function with ajax,here is a demo:
link
<script>
function myFunction() {
$.ajax({
type: "POST",
url: "https://test.testspace.space/storage/Data/stream",
data: { tokenValue: "e58367c8-ec11-4c19-995a-f37ad236e0d2", fileId: "2693", position:0 },
success: function (data) {
}
});
</script>
Since you want to make a POST request, but the values need to be as query string params in the URL, you need to use jquery.Param.
see https://api.jquery.com/jquery.param/.
You should set the params, like below :
$.ajax({
url: 'your url',
type: 'POST',
data: jQuery.param({ tokenValue: "your token", fileId : "2693", position: 0}) ,
...
Try this instead,
First remove the action url from the from
Second put the result in the success function to return response
and for parameters, I always use FormData() interface to post with Ajax
And last don't forget to include dataType, contentType, processData to not get an unexpected behavior
your code will look like this
var form_data = new FormData();
form_data.append('tokenValue' ,'add899c5-7851-4416-9b06-4587528a72db&fileId=2693');
form_data.append('position' ,'position');
$.ajax({
type: "POST",
dataType: 'json',
contentType:false,
processData:false,
data: form_data,
url: 'https://test.testspace.space/storage/Data/stream',
success: function (result) {
}
});

Ajax Request Return HTML Page

I am trying to send data from an Input to the controller of my application in Laravel, where I supply the category ID and it returns a jSON with the related id's.
I have a input to get data
<label for="categoryMae">Nome da Categoria Mãe</label>
<input class="form-control" id="getCategoryMae" name="getCategoryMae" />
A script to pass to my controller
<script>
$("#getCategoryMae").blur(function(){
var cat_id = $(this).val();
console.log(cat_id);
$.ajax({
type: 'GET',
url: '{{route('getCategoryName')}}',
data: 'cat_id',
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(data){
console.log(data.cat_id);
}
});
});
</script>
and I trying to get this values in my Controller (Route::get('/categories/getCategoryName', 'CategoriesController#getCategoryName')->name('getCategoryName');)
public function getCategoryName(Request $request)
{
$data = $request->all();
dd($data);
}
But the code returns the HTML structure and not the the value
How return only the value and not all that structure and why that happened? Thanks in advance!
I don't think you're sending any data to your controller. Try this, check the data property of the AJAX call.
<script>
$("#getCategoryMae").blur(function(){
var cat_id = $(this).val();
console.log(cat_id);
var dataObject = {cat_id: cat_id};
$.ajax({
type: 'GET',
url: '{{route('getCategoryName')}}',
data: dataObject,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(data){
console.log(data.cat_id);
}
});
});
</script>
Also, I can tell you use Google Chrome, you can make sure you send something to the server, you can click on the Headers, go to the bottom to the Query String Prameters to see the parameters you're sending.
Here's a good resource: Chrome Dev Tools

Is it possible to add multi media type to HTTP header?

I want to make a request have both JSON and file
My controller :
#Authorize(roles={UserType.ADMIN,UserType.SCHOOL_ADMIN})
#RequestMapping(value="import",method=RequestMethod.POST)
public List<AddUserResponse>importUserBundle(#RequestBody AddUserRequest test,#RequestParam(value="userCsv")MultipartFile[] userCsv)
And got error when making a request :
Content type
'multipart/form-data;boundary=----WebKitFormBoundary62tvsTfonhCQ6HSl;charset=UTF-8'
not supported
Is there any way to make a request with both multipart/form-data and application/json media type?
Your AJAX call should be like this:
$.ajax({
url: '/importUserBundle',
type: 'POST',
data: {
userCsv: FileToSend,
test: JsonData
},
dataType: 'json',
processData: false,
contentType: false,
success: function(data)
{
}
});
EDITED
processData:false Don't process the files
contentType:false Set content type to false as jQuery will tell
the server its a query string request.
Look at this for more info http://abandon.ie/notebook/simple-file-uploads-using-jquery-ajax
Hope this will help

PATCH AJAX Request in Laravel

Is it possible to make AJAX PATCH requests to laravel, or am I restricted to POST? Laravel uses PATCH in input hidden fields, however, I am not using form elements—just buttons that should partially update a record when clicked (via an AJAX request).
How would the route look like for this?
Routes file
Route::patch('questions/{id}', 'QuestionController#update')->before('admin');
I am not sure if laravel routes support PATCH.
Controller
public function update($id) {
if (Request::ajax() && Request::isMethod('patch')) {
//partially update record here
}
}
JS
$('div#question_preview <some button selector>').click(function (event) {
$.ajax({
url: 'questions/'+question_id,
type: 'PATCH',
data: {status: 'some status'}
});
});
I am just looking for clarity, thanks!
Yeah, it's possible try
In Your JavaScript
$('#div#question_preview <some button selector>').click(function() {
$.ajax({
url: 'questions/'+question_id,
type: 'PATCH',
data: {status: <SOME VALUE I WANT>, _method: "PATCH"},
success: function(res) {
}
});
});
In Your Route
Route::patch('questions/{id}', 'QuestionController#update')->before('admin');
In your QuestionController Controller's update method
dd(Request::method());
You will see the respond like
string(5) "PATCH"
Read more about Request Information on Laravel doc.
It's possible!
You should need to provide an extra parameter in the form request called as _method with a value PATCH.
JS
$('div#question_preview <some button selector>').click(function (event) {
$.ajax({
url: 'questions/'+question_id,
type: 'PATCH',
data: {status: 'some status',_method: 'PATCH'}
});
});
You can provide a hidden input in the view file with the value PATCH for better readability
HTML
<input type="hidden" name="_method" value="PATCH">
If you are using FormData, you need to send the request as POST. The Laravel application will automatically get it as a PATCH request because you included #method('PATCH'). So your route and method for that will get triggered.
JS with FormData
$('div#question_preview <some button selector>').click(function (event) {
let form_data= new FormData();
form_data.append('status','some status');
form_data.append('_method','PATCH');
$.ajax({
url: 'questions/'+question_id,
type: 'POST',
data: form_data
});
});

How to send ajax response to HTML form to store the value as hidden?

I have form where I use ajax way to upload images and like to send the uploaded images to back to form to hidden fields. How to do that? I am trying the uploaded images to be send to hidden field. like this, document.getElementById("hid").value = res;
I use the ajax code like this,
if (formdata) {
$.ajax({
url: "upload.php",
type: "POST",
data: formdata,
processData: false,
contentType: false,
success: function (res) {
document.getElementById("response").innerHTML = res;
document.getElementById("hid").value = res;
}
});
}

Resources