Correct way to pass data to Jquery Ajax - javascript

Whats the correct way to pass data to ajax using jquery. I have the following method and I want to pass the CSRF token from a meta tag but it doesn't work.
<meta name="csrf-token" content="{{ csrf_token() }}">
<div class="fallback">
<input type="file" name="logo" id="logo" class="inputfile"/>
</div>
$(document).on("change", ".fallback .inputfile", function() {
$.ajax({
url: "/upload",
type: 'POST',
cache: false,
data: {
_token: $('meta[name="csrf-token"]').attr('content')
},
files: $(":file", this),
iframe: true,
processData: false
}).complete(function(data) {
console.log(data);
// $('#img-thumb').attr('src', data.path);
// $('input[name="job_logo"]').val(data.path);
});
});
Laravel method to process the file:
public function upload(Request $request) {
if($request->hasFile('logo')) {
//upload an image to the /img/tmp directory and return the filepath.
$file = $request->file('logo');
$tmpFileName = time() . '-' . $file->getClientOriginalName();
$tmpFilePath = '/img/tmp/';
$file = $file->move(public_path() . $tmpFilePath, $tmpFileName);
$path = $tmpFilePath . $tmpFileName;
return response()->json(['path'=> $path], 200);
} else {
return response()->json(false, 200);
}
}
I've followed the documentation from the following source https://cmlenz.github.io/jquery-iframe-transport/
I get tokenmismatch error. Note this is using Laravel 5.1
* UPDATE *
Should be able to add the token directly to data attribute as the csrf token is already in my meta tag. Below is an example done using backbone.js/ruby on rails, but I'm not an expert on backbone/rails so if any one can translate that into jquery it would be helpful. (http://estebanpastorino.com/2013/09/27/simple-file-uploads-with-backbone-dot-js/)
uploadFile: function(event) {
var values = {};
var csrf_param = $('meta[name=csrf-param]').attr('content');
var csrf_token = $('meta[name=csrf-token]').attr('content');
var values_with_csrf;
if(event){ event.preventDefault(); }
_.each(this.$('form').serializeArray(), function(input){
values[ input.name ] = input.value;
})
values_with_csrf = _.extend({}, values)
values_with_csrf[csrf_param] = csrf_token
this.model.save(values, { iframe: true,
files: this.$('form :file'),
data: values_with_csrf });
}

processData: false
You've told jQuery to not convert the object containing your data into a format suitable for transmitting over HTTP.

You need to add this to your page:
$(function() {
$.ajaxSetup({ headers: { 'X-CSRF-TOKEN' : '{{ csrf_token() }}' } });
});
This is because the AJAX needs the X-CSRF-TOKEN everytime you send an AJAX request to the server (unless you turn it off, which I don't recommend).
SOURCE: my own experiences with Laravel.

Related

I get an empty error when submitting multiple forms with file uploads with ajax in laravel

my problem is while posting multiple forms with ajax in laravel, I am sending the form data without any problem, but I cannot send the file.
File is empty error. I've been dealing with this for 2 days, there is no method I haven't tried, please help me.
Apart from that, I added multipart to the form, but it still didn't work, I'm sharing my codes with you.
Sorry for my bad english.
I want it to upload 2 photos in the normal 4th form until the createProduct3 form, I tried to get them by doing the normal new formData() and I tried otherwise and I couldn't succeed.
It sends it to Laravel server side as [Object File].
My Form
<form class="form" id="createProduct4" method="POST" action="">
<input type="file" class="upload-box-title" id="urun-fotografi" name="urun_fotografi" value="Fotoğraf Seç">
<input type="file" class="upload-box-title" id="urun-dosyasi" name="urun_dosyasi" value="Dosya Seç">
</form>
My blade ajax:
function createProducts()
{
var dataString = $("#createProduct1, #createProduct2, #createProduct3, #createProduct4").serialize();
let photo = document.getElementById("urun-dosyasi").files[0];
let photo2 = document.getElementById("urun-fotografi").files[0];
console.log(photo,photo2);
$.ajax({
url: "{{ route('user.product.create') }}",
type: "POST",
data: dataString+"&urun_dosyasi="+photo+"&urun_fotografi="+photo2,
success: function( data ) {
},
error: function(xhr)
{
console.log(xhr);
}
});
}
Server Function
public function createProduct(Request $request)
{
$file = $request->file('urun_dosyasi');
$file2 = $request->file('urun_fotografi');
$filename = $file->getClientOriginalName();
$extension = $file->getClientOriginalExtension();
$filename2 = $file2->getClientOriginalName();
$extension2 = $file2->getClientOriginalExtension();
echo $filename,$extension."2. doc: ".$filename2.$extension;
}
Use multipart/form-data when your form includes any <input type="file"> elements :
<form ... enctype="multipart/form-data">
Ajax :
var form = $('#createProduct4')[0];
var data = new FormData(form);
$.ajax({
url: "{{ route('user.product.create') }}",
type: "POST",
enctype: 'multipart/form-data',
data: data,
processData: false,
contentType: false,
success: function (data) {
console.log("SUCCESS : ", data);
},
error: function (e) {
console.log("ERROR : ", e);
}
});

Laravel controller can't save files from ajax request

So I have problems with uploading my image files to controller via ajax. My partner suppose to have many images. I successfully sent my images to controller via ajax, but the files cannot be store to database for some reason. I tried to send back the files request back to console log and see only empty objects. Any solution, guys?
This is my form:
<form
id="kkpn-partnerImg-form"
method="POST"
enctype="multipart/form-data"
>
<input
id="kkpn-upload-file"
type="file"
name="partnerImg[]"
multiple
accept="image/*"
data-url="{{ route('partners.partner_upload_images.store', $partner->id) }}"
hidden
>
<button
class="btn btn-success"
id="kkpn-upload-btn"
>
Upload your images
</button>
</form>
This is my Javascript:
$(document).ready(function(){
$('#kkpn-upload-btn').on('click', openDialog)
function openDialog(){
document.getElementById('kkpn-upload-file').click();
}
$('#kkpn-partnerImg-form').on('submit', function(e){
e.preventDefault();
var formData = new FormData(this);
if ($('#kkpn-upload-file').get(0).files.length != 0) {
var uploadUrl = $('#kkpn-upload-file').data('url');
formData.append(
'_token',
$('meta[name="csrf-token"]').attr('content')
)
for (var pair of formData.entries()) {
console.log(pair[0]+ ', ' + pair[1]);
}
$.ajax(
{
url: uploadUrl,
type: 'POST',
data: formData,
cache:false,
contentType: false,
processData: false,
success: function(response){
console.log(response.data)
},
error: function(error){
console.log('Error Occured!')
}
}
)
}
})
$('#kkpn-upload-file').on('change', function(){
$('#kkpn-partnerImg-form').submit()
})
})
This is my controller:
public function store(Request $request, $id)
{
$partner = Partner::where('id', $id)->first();
foreach($request->file('partnerImg') as $fileImg){
$partnerImg = new PartnerImg;
$partnerImg->img_path = $fileImg->store('partners');
$partnerImg->partner()->associate($partner);
$partnerImg->save();
}
return response()->json([
'data' => $request->file('partnerImg')
]);
}
So it didn't give me any errors or anything, it just can't store the file and when i return my request with files, it gave me empty objects. If any one know how to solve this, please help!
And this is what I get after successfully response of ajax:
As you're uploading an array of files, have you attempted accessing them with
foreach($request->file('partnerImg[]') as $fileImg) {
in your controller?
Source: https://laracasts.com/discuss/channels/laravel/how-upload-multiple-files-using-ajax-in-laravel
For some reason, I delete everything and redo again! It works! Sorry guys! But thanks for suggestion!
first problem i have seen is that you are not passing the $id parameter on ajax
public function store(Request $request, $id)
{
$partner = Partner::find($id); //change to this!
foreach($request->file('partnerImg[]') as $fileImg){
$partnerImg = new PartnerImg;
$partnerImg->img_path = $fileImg->store('partners');
$partnerImg->partner()->associate($partner);
$partnerImg->save();
}
return response()->json([
'data' => $request->file('partnerImg[]')
]);
}

Simple Ajax in Laravel

In a Laravel app, I need to update some data in the database after a button is clicked, without reloading the page, thus requiring ajax. No data needs to parsed, only a function in one of the controllers should be invoked, so it's the simplest kind of ajax request.
Based on this example, I set up the following, but nothing happens. No error, no response from the check alert('success!'), nothing.
QUESTION: why does nothing happen? Could it be that the Javascript is not recognized at al?
Head
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Routes - web.php
Route::post('/notificationsSeen','NotificationController#seen');
Controller - NotificationController.php
public function seen() {
$userNotifications = Notification::where('user_id',Auth::id())
->where('status','new')
->update(array('status' => 'seen'));
return;
}
View
<button type="button" id="notifications"></button>
<script>
$("#notifications").on('click', function() {
$.ajax({
type:'POST',
url:'/notificationsSeen',
data:'_token = <?php echo csrf_token() ?>',
success:function(data){
alert('success!');
}
});
});
</script>
EDIT: WORKING SOLUTION
Change the contents of the box above labeled "View" to the following:
<button type="button" id="notifications"></button>
<script>
(function ($) {
$(document).ready(function() {
$('#notifications').on('click', function() {
$.ajax({
url: '/notificationsSeen',
type: 'POST',
data: { _token: '{{ csrf_token() }}' },
success:function(){alert('success!');},
error: function (){alert('error');},
});
});
});
}(jQuery));
</script>
In your AJAX request, data is not a string. It is a key value pair. So use
data: { _token: '{{ csrf_token() }}' }
You shouldn't pass the csrf token like this:
data:'_token = <?php echo csrf_token() ?>',
You have to store it in a HTML meta tag:
<meta name="csrf-token" content="{{ csrf_token() }}">
Then automatically add the token to all request headers:
$( document ).ready(function() {
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$("#notifications").on('click', function() {
$.ajax({
type:'POST',
url:'/notificationsSeen',
data: {status: 'seen'},
success:function(data){
alert('success!');
}
});
});
});
Controller:
public function seen() {
$userNotifications = Notification::where('user_id',Auth::id())
->where('status','new')
->update(array('status' => request()->input('status')));
return ['success' => true];
}

TokenMismatchException with javascript x-editable on Laravel 5.3

Before marking it as duplicated, i tried the other solutions found on the web, including SO, and none of them solved my issue.
I'm using x-editable plugin to store a new record using a store route.
When the form is submitted, i get a 500 with TokenMismatchException error.
I know about setting the csrf token thing, but i tried it in several ways, and nothing is working.
That's my javascript code:
$.fn.editable.defaults.params = function (params) {
params._token = window.Laravel.csrfToken;
return params;
};
$('.editable').each(function () {
$(this).editable();
});
The html
<head>
[...]
<meta name="csrf-token" content="{{ csrf_token() }}">
[...]
<script>
window.Laravel = <?php
echo json_encode([
'csrfToken' => csrf_token(),
]);
?>
</script>
[...]
</head>
<button id="note-asl-text"
data-type="textarea"
data-placeholder="Aggiungi Nota"
data-url="{{route('ricettanota.store')}}"
data-title="Inserisci una nuova nota"
data-highlight="false"
data-mode="inline"
data-send="always"
data-showbuttons="bottom"
class="editable"
>Aggiungi nota</button>
The Route
Route::resource('ricettanota', 'RicettaNotaController');
I already tried all possible combinations of the following:
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': window.Laravel.csrfToken
}
});
$('.editable').each(function () {
$(this).editable({
ajaxOptions: {contentType: 'application/json', dataType: 'json'},
params: function (params) {
params._token = window.Laravel.csrfToken;
return JSON.stringify(params);
}
});
});
note
$('meta[name="csrf-token"]').attr('content') and window.Laravel.csrfToken are the same
update
I found out that placing Route::resource('ricettanota', 'RicettaNotaController'); into the api routes file(api.php) causes the issue, while placing the routes into the web routes file (web.php) and using the code above works.
Why using the API i get token mismatch, is still a mystery.
Not sure if this is what you are looking for, but maybe you should not struggling in sending custom header with x-editable plugin, but sending custom parameters.
The following code works for me.
$(document).ready(function() {
$.fn.editable.defaults.mode = 'popup';
$('.node').editable(
{
params: function(params) {
var data = {};
data['_csrf_token'] = $(this).data("csrf");
return data;
},
}
);
});
Set csrf in your a-tag or somewhere else you like.
<a href="#" ... data-csrf="xxxxxxx" /a>
Hope this helps.
try this in your ajaxSetup
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
I also faced same issue in Laravel 5.8. Following code worked for me.
$.fn.editable.defaults.ajaxOptions = {
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
};
this is use code
$.ajax({
type: 'POST',
url: url,
headers: {'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')},
dataType:'html',
data:data,
success:function(data){
}});
this Follow link
https://laravel.com/docs/5.3/csrf#csrf-x-csrf-token

Ajax upload not working codeigniter

I am using codeigniter 3.1 . I want to post upload data using ajax.
Ajax upload file not working. But when i post the simple form without ajax, it working fine.
I don't know why but no error in console.
HTML
<?php echo form_open_multipart(site_url("upload/post"), ['id' => 'uploader']) ?>
<input type="file" name="userfile" value="">
<input type="submit" value="Submit" />
<?php echo form_close() ?>
JAVASCRIPT
$('#uploader').submit(function (event) {
event.preventDefault();
$.ajax({
url: window.location.href + '/post',
type: "POST",
dataType: 'json',
data: new FormData(this)
});
});
CONTROLLERS
public function post()
{
$this->load->helper('url');
$this->load->helper('form');
$this->load->library("upload");
$file = $this->common->nohtml($this->input->post("userfile"));
$this->upload->initialize(array(
"upload_path" => 'upload',
"overwrite" => FALSE,
"max_filename" => 300,
"encrypt_name" => TRUE
));
$this->upload->do_upload('userfile');
$data = $this->upload->data();
$image_file = $data['file_name'];
}
Another approach to this would be passing to PHP the file encoded in base64:
get the selected file from #userfile field using $('#userfile').prop('files')[0];
transform the contents of that file into a base64 encoded string using FileReader.readAsDataURL(). We're going to call this content; Here's a similar question showing how to do and expanding the answer & possibilities;
send the AJAX passing both the filename and content strings;
now on CI, fetch the POST data;
base64_decode() the content;
fwrite() the result into a file using the filename.
That way also you could avoid POSTing all form fields.
try this..
Post data using FormData() formdata post file also.
To get all your form inputs, including the type="file" you need to use FormData object.
$('#post').on('click', function (e) {
var file_data = $("#userfile").prop("files")[0];
var form_data = new FormData();
form_data.append("userfile", file_data)
$.ajax({
url: window.location.href+'/post',
type: 'POST',
data: form_data,
async: false,
success: function (data) {
alert(data)
},
cache: false,
contentType: false,
processData: false
});
return false;
});
For more...https://abandon.ie/notebook/simple-file-uploads-using-jquery-ajax
One of the issues is that file uploading uses a different mechanism than the other form <input> types. That is why $this->input->post("userfile") isn't getting the job done for you. Other answers have suggested using javascript's FormData and this one does too.
HTML
A very simple form for picking a file and submitting it. Note the change from a simple button to <input type="submit".... Doing so makes it a lot easier for the javascript to use the FormData object.
FormData documentation
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<script src="https://code.jquery.com/jquery-2.2.2.js"></script>
<title>Upload Test</title>
</head>
<body>
<?= form_open_multipart("upload/post", ['id' => 'uploader']); ?>
<input type="file" name="userfile">
<p>
<input type="submit" value="Upload">
</p>
<?php echo form_close() ?>
<div id="message"></div>
<script>
$('#uploader').submit(function (event) {
event.preventDefault();
$.ajax({
url: window.location.href + '/post',
type: "POST",
dataType: 'json',
data: new FormData(this),
processData: false,
contentType: false,
success: function (data) {
console.log(data);
if (data.result === true) {
$("#message").html("<p>File Upload Succeeded</p>");
} else {
$("#message").html("<p>File Upload Failed!</p>");
}
$("#message").append(data.message);
}
});
});
</script>
</body>
</html>
JAVASCRIPT
Use FormData to capture the fields.
Note that instead of handling the button click we handle the submit event.
$('#uploader').submit(function (event) {
event.preventDefault();
$.ajax({
url: window.location.href + '/post',
type: "POST",
dataType: 'json',
data: new FormData(this),
processData: false,
contentType: false,
success: function (data) {
//uncomment the next line to log the returned data in the javascript console
// console.log(data);
if (data.result === true) {
$("#message").html("<p>File Upload Succeeded</p>");
} else {
$("#message").html("<p>File Upload Failed!</p>");
}
$("#message").append(data.message);
}
});
});
CONTROLLER
I've added some code that "reports" results to ajax and will display it on the upload page.
class Upload extends CI_Controller
{
public function __construct()
{
parent::__construct();
$this->load->helper(['form', 'url']);
}
public function index()
{
$this->load->view('upload_v');
}
public function post()
{
$this->load->library("upload");
$this->upload->initialize(array(
"upload_path" => './uploads/',
'allowed_types' => 'gif|jpg|png|doc|txt',
"overwrite" => FALSE,
"max_filename" => 300,
"encrypt_name" => TRUE,
));
$successful = $this->upload->do_upload('userfile');
if($successful)
{
$data = $this->upload->data();
$image_file = $data['file_name'];
$msg = "<p>File: {$image_file}</p>";
$this->data_models->update($this->data->INFO, array("image" => $image_file));
} else {
$msg = $this->upload->display_errors();
}
echo json_encode(['result' => $successful, 'message' => $msg]);
}
}
This will upload your file. Your work probably isn't done because I suspect that your are not saving all the file info you need to the db. That, and I suspect you are going to be surprised by the name of the uploaded file.
I suggest you study up on how PHP handles file uploads and examine some of the similar codeigniter related questions on file uploads here on SO.
Controller
public function upload()
{
$this->load->library('upload');
if (isset($_FILES['myfile']) && !empty($_FILES['myfile']))
{
if ($_FILES['myfile']['error'] != 4)
{
// Image file configurations
$config['upload_path'] = './upload/';
$config['allowed_types'] = 'jpg|jpeg|png';
$this->upload->initialize($config);
$this->upload->do_upload('myfile');
}
}
}
View
<form id="myform" action="<?php base_url('controller/method'); ?>" method="post">
<input type="file" name="myfile">
("#myform").submit(function(evt){
evt.preventDefault();
var url = $(this).attr('action');
var formData = new FormData($(this)[0]);
$.ajax({
url: url,
type: 'POST',
data: formData,
processData: false,
contentType: false,
success: function (res) {
console.log(res);
},
error: function (error) {
console.log(error);
}
}); // End: $.ajax()
}); // End: submit()
Let me know if any query
you need to submit the form not on click but on submit ... give the form an id and then on submit put ajax
HTML
<?php $attributes = array('id' => 'post'); ?>
<?php echo form_open_multipart(site_url("upload/post",$attributes), ?>
<input type="file" id="userfile" name="userfile" value="">
<button id="post">Submit</button>
<?php echo form_close() ?>
JAVASCRIPT
$('#post').on('submit', function () {
var formData = new FormData();
formData.append("userfile",$("#userfile")[0].files[0]);
$.ajax({
url: window.location.href+'/post',
type: "POST",
data: formData
});
CONTROLLERS
public function post()
{
$this->load->library("upload");
$file = $this->common->nohtml($this->input->post("userfile"));
$this->upload->initialize(array(
"upload_path" => 'upload',
"overwrite" => FALSE,
"max_filename" => 300,
"encrypt_name" => TRUE,
));
$data = $this->upload->data();
$image_file = $data['file_name'];
$this->data_models->update($this->data->INFO, array(
"image" => $image_file
)
);
}

Categories