웹 프로그램을 작성하는 과정에서 우리는 아바타(사진) 업로드라는 고전적인 파일 업로드 시나리오를 자주 접하게 됩니다. 최고의 사용자 경험 추구를 바탕으로 이전에 Laravel 프로젝트에서 구현한 Ajax
업로드 아바타에 대해 작성해 보겠습니다. Ajax
上传头像。
1.配置路由
在Laravel的routes.php
中设置路由:
Route::get('/avatar/upload','UsersController@avatar'); Route::post('/avatar/upload','UsersController@avatarUpload');
2.配置控制器
在UsersController.php
中增加对应的avatar
和avatarUpload
这两个方法,前者用来渲染视图,后者处理实际上传的图像文件。
public function avatar() { return view('users.avatar'); } public function avatarUpload() { //some codes to deal with upload avatar }
3.编写前端代码
这其实就是在对应的users/
文件夹的avatar.blade.php
视图文件中设置样式,以下的HTML的各个标签可以根据自己的情况设置class
和id
:
<header class="profile-header"> <img id="user-avatar" src="https://wt-prj.oss.aliyuncs.com/0d06af79c49d4e08abb1ab3f7ab6e860/772c684b-10a4-43cf-8eec-dda9e28a5a23.png"> <p id="validation-errors"></p> <p 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() !!} <p class="span5"> <p id="output" style="display:none"> </p> </p> <span id="filename"></span> </header>
在js中实现Ajax请求,这里的Ajax借助了Jquery的第三方插件http://malsup.com/jquery/form/:
$(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('<p class="alert alert-error"><strong>'+ value +'</strong><p>'); } }); $("#validation-errors").show(); } else { $('#user-avatar').attr('src',response.avatar); } }
4.处理上传的图片
回到UsersController.php
中的avatarUpload
方法,现在就可以处理上传上来的图片了:
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/
文件夹,并给以相应的权限,如:
sudo chmod -R 777 uploads/
在上面的avatarUpload
方法中,有一个wrongTokenAjax
方法,这是用来检验Laravel体系的token
值的,同样是在UsersController.php
中添加:
public function wrongTokenAjax() { if ( Session::token() !== Request::get('_token') ) { $response = [ 'status' => false, 'errors' => 'Wrong Token', ]; return Response::json($response); } }
5.最后
到这里一个简单的Ajax
上传图片的demo就完成了,在实际的开发中,我们还需要考虑以下几个问题:
-
根据用户的不同用户名或者用户id来创建不同的文件夹,这些都可以在
avatarUpload
方法中$file->move($destinationPath, $filename)
之前使用File::exists($username) or File::makeDirectory($username);
-
更新数据库中用户的
avatar
字段,大概是这样的:在avatarUpload
方法返回数据之前,使用下面的类似语句:$user->avatar = your_avtar_upload_path; $user->save();
-
如果你还想更进一步改善体验,提供一些图片的裁剪和添加滤镜等功能,可以同时使用 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
1. 라우팅 구성
Laravel의routes.php
에서 라우팅 설정: rrreee
2. 컨트롤러 구성
avatar
및 avatarUpload
메소드를 .php로 변환합니다. 전자는 뷰를 렌더링하는 데 사용되고 후자는 실제로 업로드된 이미지 파일을 처리합니다.