在Laravel項目中實現Ajax上傳用戶頭像

在編寫web程序的過程當中,常常會遇到一個經典的文件上傳場景:上傳頭像(圖片)。基於對最好的用戶體驗的追求,寫一下以前在項目中實如今Laravel項目中的Ajax上傳頭像。php

1.配置路由

在Laravel的routes.php中設置路由:css

Route::get('/avatar/upload','UsersController@avatar');
Route::post('/avatar/upload','UsersController@avatarUpload');

2.配置控制器

UsersController.php中增長對應的avataravatarUpload這兩個方法,前者用來渲染視圖,後者處理實際上傳的圖像文件。html

public function avatar()
    {

        return view('users.avatar');
    }

  public function avatarUpload()
    {
    //some codes to deal with upload avatar
    }

3.編寫前端代碼

這其實就是在對應的users/文件夾的avatar.blade.php視圖文件中設置樣式,如下的HTML的各個標籤能夠根據本身的狀況設置classid:前端

<header class="profile-header">
 <img id="user-avatar" src="https://wt-prj.oss.aliyuncs.com/0d06af79c49d4e08abb1ab3f7ab6e860/772c684b-10a4-43cf-8eec-dda9e28a5a23.png">


<div id="validation-errors"></div>




<

div class="avatar-upload" id="avatar-upload">
 {!! Form::open( [ 'url' => ['/avatar/upload/api'], 'method' => 'POST', 'id' => 'upload', 'files' => true ] ) !!}
<a href="#" class="btn button-change-profile-picture">
<label for="upload-profile-picture">
<span id="upload-avatar">更換新頭像</span>
 <input name="image" id="image" type="file" class="manual-file-chooser js-manual-file-chooser js-avatar-field">
</label>
</a>
{!! Form::close() !!}


<div class="span5">
<div id="output" style="display:none">
</div>
</div>


<span id="filename"></span>
 </header>

在js中實現Ajax請求,這裏的Ajax藉助了Jquery的第三方插件http://malsup.com/jquery/form/jquery

$(document).ready(function() {
            var options = {
                beforeSubmit:  showRequest,
                success:       showResponse,
                dataType: 'json'
            };
            $('#image').on('change', function(){
                $('#upload-avatar').html('正在上傳...');
                $('#upload').ajaxForm(options).submit();
            });
        });
    function showRequest() {
        $("#validation-errors").hide().empty();
        $("#output").css('display','none');
        return true;
    }

    function showResponse(response)  {
        if(response.success == false)
        {
            var responseErrors = response.errors;
            $.each(responseErrors, function(index, value)
            {
                if (value.length != 0)
                {
                    $("#validation-errors").append('<div class="alert alert-error"><strong>'+ value +'</strong><div>');
                }
            });
            $("#validation-errors").show();
        } else {

          $('#user-avatar').attr('src',response.avatar);

        }
    }

4.處理上傳的圖片

回到UsersController.php中的avatarUpload方法,如今就能夠處理上傳上來的圖片了:laravel

public function avatar()
    {
        $this->wrongTokenAjax();
        $file = Input::file('image');
        $input = array('image' => $file);
        $rules = array(
            'image' => 'image'
        );
        $validator = Validator::make($input, $rules);
        if ( $validator->fails() ) {
            return Response::json([
                'success' => false,
                'errors' => $validator->getMessageBag()->toArray()
            ]);

        }

        $destinationPath = 'uploads/';
        $filename = $file->getClientOriginalName();
        $file->move($destinationPath, $filename);
                return Response::json(
                    [
                        'success' => true,
                        'avatar' => asset($destinationPath.$filename),
                    ]
                );
            }



    }

注:在上傳以前,確認在laravel的public/目錄下建立了uploads/文件夾,並給以相應的權限,如:web

sudo chmod -R 777 uploads/

在上面的avatarUpload方法中,有一個wrongTokenAjax方法,這是用來檢驗Laravel體系的token值的,一樣是在UsersController.php中添加:ajax

public function wrongTokenAjax()
    {
        if ( Session::token() !== Request::get('_token') ) {
            $response = [
                'status' => false,
                'errors' => 'Wrong Token',
            ];

            return Response::json($response);
        }

    }

5.最後

到這裏一個簡單的Ajax上傳圖片的demo就完成了,在實際的開發中,咱們還須要考慮如下幾個問題:數據庫

  1. 根據用戶的不一樣用戶名或者用戶id來建立不一樣的文件夾,這些均可以在avatarUpload方法中 $file->move($destinationPath, $filename)以前使用json

    File::exists($username) or File::makeDirectory($username);
  2. 更新數據庫中用戶的avatar字段,大概是這樣的:在avatarUpload方法返回數據以前,使用下面的相似語句:

    $user->avatar = your_avtar_upload_path;
    
    $user->save();
  3. 若是你還想更進一步改善體驗,提供一些圖片的裁剪和添加濾鏡等功能,能夠同時使用 Intervention/Image php包和Jcrop js圖片裁剪實現,好比在:

    function showResponse(response)  {
    
    }

    中,若是成功的返回圖片,就在$('#user-avatar').attr('src',response.avatar)後執行:

    $('#user-avatar').Jcrop({
                    aspectRatio: 1,
                    onSelect: updateCoords,
                    setSelect: [120,120,10,10]
                    });

    就能夠在前端實現圖片裁剪,而後將相應的裁剪數據如裁剪圖片的height,width,x-align.y-align等傳到後端處理就能夠,使用Intervention/Image的話,在後端處理圖片就是垂手可得的事情了!

Happy Hacking

相關文章
相關標籤/搜索