【问题标题】:How to upload a CSV file using AJAX with custom prefilter in laravel 4.2如何在 laravel 4.2 中使用带有自定义预过滤器的 AJAX 上传 CSV 文件
【发布时间】: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 但包含时我不知道接受自定义请求。

标签: php jquery ajax laravel laravel-4


【解决方案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 更好的解决方案? stackoverflow 的整个想法是分享结果和/或将答案标记为解决方案......谢谢
【解决方案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]);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-08-22
    • 1970-01-01
    • 1970-01-01
    • 2015-03-22
    • 2012-04-24
    • 2014-12-17
    • 2014-12-15
    • 1970-01-01
    相关资源
    最近更新 更多