插件
使用ajax
来实现上传功能,需要用到jquery.html5-fileupload.js
这样一个插件。这个插件我自己用的非常顺手,而且用法也非常的简单,所以我就推荐给大家来使用了。
插件的下载地址,大家可以在课程的资料中找到。https://github.com/AaronRyuu/laravel_tricks/blob/master/public/assets/js/jquery.html5-fileupload.js
有了这个插件后,放到public/assets/js
目录中。
controller
这一次我们实现上传,就不在RegisterController
中了,来自己新建一个叫做photos
的控制器。里面就写一个store
方法,然后把之前RegisterController
中register
方法中所有代码,都剪切过来。RegisterController
一些多余的代码,我们也清理掉。
php artisan make:controller PhotosController
use Illuminate\Support\Facades\Storage;
class PhotosController extends Controller
{
public function store(Request $request)
{
//...
}
}
route
配置一下路由,只需要一个store
Route::resource('photos', 'PhotosController', ['only' => 'store']);
views
app.blade.php
布局模板中,先到head
里,加上这么一段代码。
这还是因为 csrf token 的原因,使用ajax
的方式来提交数据,就得有这么一行代码。一会在js
中还要来读取这里面的数据。
底部body
标签之前,加一个yield
<head>
<meta name="csrf-token" content="{{ csrf_token() }}">
</head>
<body>
<!-- ... -->
@yield('scripts')
</body>
基础格式
打开register.blade.php
,底部咱们加上对应的js
代码。
先要引用这个插件。
先要加一个ajaxSetup
,它的意思就是,读取meta
标签里的csrf field
。并在发送ajax
的时候,将这个值也发送给php
。
插件的调用也非常简单,就只有几个参数需要设置一下。最底下的这行代码,就是启动插件了。
@section('scripts')
<script src="/assets/js/jquery.html5-fileupload.js"></script>
<script>
//发送ajax请求时,带上csrf token
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
//插件的配置
var opts = {
url: "/photos",
type: "POST",
//上传之前
beforeSend: function () {
},
//上传成功后
success: function (result, status, xhr) {
},
//上传失败
error: function (result, status, errorThrown) {
}
}
//启动
$('#photo_upload').fileUpload(opts);
</script>
@endsection
现在打开chrome
的network
,来调试一下试试。可以正常的返回信息了。
PhotosController
修改store方法
,成功后
return response()->json(['message' => 'success', 'data' => $url], 200);
完整 js
再来继续完善一下插件的方法。
<script>
//发送ajax请求时,带上csrf token
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
//插件的配置
var opts = {
url: "/photos",
type: "POST",
//上传之前
beforeSend: function () {
$("#loading").attr("class", "am-icon-spinner am-icon-pulse");
},
//上传成功后
success: function (result, status, xhr) {
$("input[name='avatar']").val(result.data);
$("#photo_show").attr('src', result.data);
$("#loading").attr("class", "am-icon-cloud-upload");
},
//上传失败
error: function (result, status, errorThrown) {
alert(result.responseJSON.message)
$("#loading").attr("class", "am-icon-cloud-upload");
}
}
//启动
$('#photo_upload').fileUpload(opts);
</script>
在上传之前,我希望呢,这里的图标能有一点变换,能让用户感觉到现在是在上传文件了。
成功后,需要设置这个隐藏的input
的value
和 img标签
的src
。
隐藏的input
后面会通过sign up
按钮,把图片的路径保存到数据库。img标签
的设置,就是为了让图片能马上显示出来。
还有不要忘记了,将上传过程中旋转的图标,恢复过来。
如果上传的文件有问题,例如格式不正确,这个信息就在error
方法中来输出了。格式是result.responseJSON.message
,最后也不要忘记了把上传图标恢复原状了。
RegisterController
还有一点点需要修改的是,控制器中,不要忘记了加上avatar
protected function create(array $data)
{
return User::create([
//...
'avatar' => $data['avatar'],
]);
}
整理
ajax 上传头像的功能就这样实现了,最后整理一下代码。
$.ajaxSetup
这段代码应该是公用的,所以我们把它拿到common.js
中。
再到public/assets/js
里,新建一个upload.js
,将插件的调用代码,都挪过去。
模板里,改为引用upload.js
,重新来上传,功能依然是好用的。
@section('scripts')
<script src="/assets/js/jquery.html5-fileupload.js"></script>
@endsection