如何在 laravel 4.2 中使用带有自定义预过滤器的 AJAX 上传 CSV 文件
Posted
技术标签:
【中文标题】如何在 laravel 4.2 中使用带有自定义预过滤器的 AJAX 上传 CSV 文件【英文标题】:How to upload a CSV file using AJAX with custom prefilter in laravel 4.2 【发布时间】:2016-01-22 19:48:07 【问题描述】:我正在使用 laravel 4.2,目前我不知道如何使用 AJAX 将 csv 文件保存到 public\csv\
目录中。我仍在寻找一些答案。也许有人可以帮助我。
这是我的代码:
在刀片视图中:
Form::open(['route' => 'file_upload', 'files' => true, 'id' => 'upload_form', 'method' => 'POST'])
Form::file('csv_upload', ['id' => 'uploaded_file', 'accept' => 'text/csv'])
Form::submit('submit', ['class' => 'btn btn-primary btn-xs', 'id' => 'upload'])
Form::close()
javascript Ajax:
var ajax_ready = 1
var token = Session::get('_token')
if($.type(originalOptions.data) === 'string')
options.data = originalOptions.data+"&_token="+token;
else if($.type(originalOptions.data) === 'object')
//Here I got a new error
else
options.data = $.param(($.extend(originalOptions.data, '_token':mmad_token)));
options.url = originalOptions.url.slice(0,originalOptions.url.indexOf("?_token="));
if (ajax_ready!=1)
jqXHR.abort();
ajax_ready = 0;
);
$('form#upload_form').on('submit', function(e)
e.preventDefault();
var uploadFile = $('#uploaded_file');
var ext = $("input#uploaded_file").val().split(".").pop().toLowerCase();
var file = $('input[name="csv_upload"]').val();
if($.inArray(ext, ["csv"]) === -1)
alert("Please upload a .csv file!");
return false;
var csv = uploadFile[0].files;
var form = new FormData(this);
var csvFile = lastModifed: csv[0].lastModified, fileName: csv[0].name, size: csv[0].size, fileType: csv[0].type;
$.post(' URL::route("file_upload") ?_token=Session::token()',
data: form
).done(function(response)
);
);
php:
public function upload_csv()
$inputs = Input::all();
$csvFile = $inputs['data']['fileName'];
$path = public_path().DIRECTORY_SEPARATOR.'csv'.DIRECTORY_SEPARATOR;
$path2 = public_path('csv/');
if(is_dir($path2))
@move_uploaded_file($csvFile, $path2.$csvFile); //This line can't move the uploaded files in my desired directory
return json_encode(['success' => 1, 'description' => 'Successfully Upload File']);
以下代码在不使用 AJAX 时确实有效:
if(Input::hasFile('csv_upload'))
$file = Input::file('csv_upload');
$originalFilename = $file->getClientOriginalName();
$rules = ['csv_upload' => 'required|file:csv'];
$validate = Validator::make(['csv_upload' => $file], $rules);
if($validate->fails())
return json_encode(['error' => 1, 'description' => 'File must be in .csv format']);
$path = public_path('/csv/');
if(!file_exists($path))
mkdir($path);
csv 的控制台日志
【问题讨论】:
你不认为你需要通过 csrf 令牌...afaik 你需要通过 我将更新我的问题,因为我目前将 csrf 令牌与 url 一起发送。 为什么不使用 plupload 库,它可以将文件发布到您的 url。它将与您现有的控制器一起使用。 其他代码工作正常,但使用 ajaxprefilter 但包含时我不知道接受自定义请求。 【参考方案1】:要将上传的文件移动到新位置,您应该使用 move 方法。此方法会将文件从其临时上传位置(由您的 PHP 配置确定)移动到您选择的更永久的目的地:
Input::file('fileName')->move($destinationPath, $fileName);
如果您需要额外的验证,可以在http://laravel.com/docs/5.1/requests#files查看它
【讨论】:
是的,但我就是这样做的。仍然无法正常工作,所以我选择上传文件的本机。 请求参数是ajax格式。问题是如果我做 ajax 上传的文件没有存储到临时文件中。 你在 laravel 中获取文件对象吗?检查this solution 不,我得到了一个对象数组。在上图中 当我使用FormData()
然后通过ajax的数据传递它。我得到非法调用。【参考方案2】:
您不能移动文件,因为当您使用 ajax 提交表单时 文件没有被发送 使用 ajax,要发送文件,您必须使用 FormData() javascript 发送文件对象。
如果您通过输入print_r($_FILES);
签入upload_csv
控制器,您将得到空数组。
所以在客户端使用FormData 附加文件,然后尝试agian。
您没有收到错误,因为您使用了 php 错误控制运算符 likes@move_uploaded_file($csvFile, $path2.$csvFile);
。
如果您需要工作示例,请告诉我,我会给您。
为您提供帮助的代码: 1. 在刀片视图中:
<script type="text/javascript">
$('form#upload_form').on('submit', function(e)
e.preventDefault();
var uploadFile = $('#uploaded_file');
var ext = $("input#uploaded_file").val().split(".").pop().toLowerCase();
var file = $('input[name="mmad_csv_upload"]').val();
if($.inArray(ext, ["csv"]) === -1)
alert("Please upload a .csv file!");
return false;
var csv = uploadFile[0].files;
var formData = new FormData($(this)[0]);
formData.append('uploaded_file', $("#uploaded_file")[0].files[0]);
formData.append('lastModifed', csv[0].lastModified);
formData.append('fileName', csv[0].name);
console.log(formData);
$.ajax(
url: ' URL::route("file_upload") ',
type: 'POST',
data: formData,
async: true,
cache: false,
contentType: false,
processData: false,
success: function (returndata) //alert(returndata); return false;
);
);
</script>
2.控制器
public function file_upload(Request $request)
$inputs = Input::all();
$csvFile = $inputs['fileName'];
$path = public_path().DIRECTORY_SEPARATOR.'csv'.DIRECTORY_SEPARATOR;
$path2 = public_path('/csv/');
if(is_dir($path2))
$success = $request->file('uploaded_file')->move($path2, $csvFile);
return json_encode(['success' => 1, 'description' => 'Successfully Upload File']);
【讨论】:
你能给我吗?我想使用Input::file('filename')
获取数据文件
我已经编辑了我的答案并添加了代码。请检查。
好的,我明天试试。
它说是Error: Illegal invocation
。
你已经使用了 jQuery 的 $.post() 函数,而不是你必须为 formdata() 使用 $.ajax 函数,你改变了那个。你得到非法调用是因为 jQuery 试图序列化 $.post 的 jQuery 对象,但它不能。它可能试图调用一个字符串方法,并将一个 jQuery 对象作为上下文传递给它,从而导致错误。【参考方案3】:
默认 AJAX POST 不支持文件上传。使用 jQuery Form 成功上传文件。文件上传的完整文档http://malsup.com/jquery/form/#file-upload
下面是我最近构建脚本的示例...我的控制器将文件上传到 S3,但很容易使用本地存储实现。
var progress = function(event, position, total, percent)
$(".progress-bar").width(percent + '%');
$(".progress-bar").html(percent + '%');
if(percent > 50)
$(".progress-bar").css('color','#fff');
if(percent == 100)
setTimeout(function()
$(".progress").html('<span class="processing-msg">Processing... Please be patient!</span>');
$(".processing-msg").fadeIn('slow');
, 1000);
var success = function(data)
var obj = $.parseJSON(data);
$("#"+obj.hidden, parent.document).val(obj.filename);
var src = 'https://s3.amazonaws.com/spincms'+obj.path+'thumb_'+obj.filename;
$("#uploaded-"+obj.hidden, parent.document).html('<img class="img-circle uploaded-img" src="' + src + '">');
$(".progress").html('<span class="processing-msg-next">File has been uploaded and processed. Do not forget to submit the form!</span>');
var options =
target: '#output',
uploadProgress: progress,
success: success,
resetForm: true
;
$(document).on('click', "#upload-now", function(e)
$(".progress").html('<div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100"></div>');
if($("#upload-form input[type=file]")[0].files.length == 0)
$(".progress").html('<span class="processing-msg-next">No file selected!</span>');
return false;
else
var name = $("#upload-form input[name='name']").val();
var token = $("#upload-form input[name='_token']").val();
var file_name = $("#upload-form input[type=file]")[0].files[0].name;
$("#upload-form").ajaxSubmit(options);
);
【讨论】:
有什么比@aldrin27 更好的解决方案? *** 的整个想法是分享结果和/或将答案标记为解决方案......谢谢【参考方案4】:由于您使用的是 jQuery,因此您可以使用 form plugin,因为它会让您更轻松地使用它,例如,这是您将使用的 jquery 部分:
$(document).ready(function()
// bind 'myForm' and provide a simple callback function
$('#upload_form').ajaxForm(function()
alert("Your file has been uploaded, thanks");
);
);
在您的控制器中,您可以像这样编写代码:
pubilc function postUpload()
$success = false;
if(Request::ajax())
if(Input::hasFile('csv_upload'))
$file = Input::file('csv_upload');
if(!File::isDirectory(storage_path('csv')))
File::createDirectory(storage_path('csv'));
$file->move(storage_path('csv'), $file->getClientOriginalName());
// now your file is on app/storage/csv folder
$filePath = storage_path('csv/'.$file->getClientOriginalName());
$success = true;
return Response::json(['success'=>$success]);
【讨论】:
以上是关于如何在 laravel 4.2 中使用带有自定义预过滤器的 AJAX 上传 CSV 文件的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Laravel 4.2 中创建自定义 DB Query Builder 方法
如何将控制器中的 Laravel 4.2 beforeFilter 转换为 Laravel 5.2 中的自定义中间件