In the process of writing web programs, we often encounter a classic file upload scenario: upload Avatar (picture). Based on the pursuit of the best user experience, write about the Ajax
uploading avatar implemented in the Laravel project before.
1. Configure routing
Set routing in Laravel’s routes.php
:
Route::get('/avatar/upload','UsersController@avatar'); Route::post('/avatar/upload','UsersController@avatarUpload');
2. Configure controller
Add the corresponding avatar
and avatarUpload
methods in UsersController.php
. The former is used to render the view, and the latter processes the actually uploaded image file.
public function avatar() { return view('users.avatar'); } public function avatarUpload() { //some codes to deal with upload avatar }
3. Write the front-end code
This is actually set in the avatar.blade.php
view file of the corresponding users/
folder Style, each tag of the following HTML can be set according to your own situation class
and 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>
to implement Ajax requests in js, the Ajax here uses Jquery Third-party plug-in 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. Process the uploaded image
Return to UsersController.php
##avatarUpload method, you can now process the uploaded image:
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), ] ); } }
Note: Before uploading, confirm that it is created in laravel'sIn the abovepublic/
directory
uploads/folder, and give corresponding permissions, such as:
sudo chmod -R 777 uploads/Copy after login
avatarUpload method, there is a
wrongTokenAjaxMethod, this is used to test the
token value of the Laravel system. It is also added in
UsersController.php:
public function wrongTokenAjax() { if ( Session::token() !== Request::get('_token') ) { $response = [ 'status' => false, 'errors' => 'Wrong Token', ]; return Response::json($response); } }
A simple
Ajax demo for uploading images is now complete. In actual development, we also need to consider the following issues:
- ## Create different folders based on the user's different usernames or user ids. These can be used before the
- avatarUpload
method
$file->move($destinationPath, $filename)
<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">File::exists($username) or File::makeDirectory($username);</pre><div class="contentsignin">Copy after login</div></div>
Update the user's - avatar
field in the database, probably like this: Before the
avatarUpload
method returns the data, use a similar statement below :<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">$user->avatar = your_avtar_upload_path; $user->save();</pre><div class="contentsignin">Copy after login</div></div>
If you want to further improve the experience and provide some image cropping and adding filters, you can use the Intervention/Image php package and Jcrop js image cropping at the same time. For example, in: -
function showResponse(response) { }
Copy after login, if the image is successfully returned, execute after
$('#user-avatar').attr('src',response.avatar):
height<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false"> $('#user-avatar').Jcrop({ aspectRatio: 1, onSelect: updateCoords, setSelect: [120,120,10,10] });</pre><div class="contentsignin">Copy after login</div></div>
You can implement image cropping on the front end, and then add the corresponding cropping data such as,
width
,x-align
of the cropped image.y-align
Just wait until it is sent to the backend for processing. If you use Intervention/Image, processing images on the backend is a piece of cake!