这两天在尝试Laravel自带的文件上传。Laravel作为十分强大的框架,自带了文件上传的实现,但是默认的配置上传文件都是保存在项目目录内的,这是十分不提倡的方式,比较好的方式就是我们将上传文件保存目录和项目分离开。
配置文件config/filesystem.php修改
laravel框架的config/filesystem文件包含了laravel自带上传功能的相关配置
默认的上传文件采用本地驱动,保存在根目录的storage目录下,
public是例如图片等允许公共访问资源的路径,s3我们暂不理会
把local->root的值修改为要保存文件的文件夹绝对路径
例如我们要保存文件到f:\upload文件夹下,修改local->‘root’=‘f:\upload’
前端实现:
<form class="form-inline center-block" id="ajax-upload" enctype="multipart/form-data" action="{{route('users.upload')}}" method="post">
{{csrf_field()}}
<input class="form-control" type="file" name="file">
<button class="btn btn-primary" type="submit">上传文件</button>
</form>
请注意,文件上传是一定要设置表单enctype属性=“multipart/form-data”
我这里是通过ajax异步提交,还用到了FormData序列化表单数据
ajax提交表单的实现:
$('#ajax-upload').submit(function () {
event.preventDefault();
var url = $('#ajax-upload').attr('action');
var formData = new FormData($('#ajax-upload')[0])
$.ajax({
url: url,
type: 'POST',
data: formData,
//请求的媒体类型
processData: false, //记得加这两条,否则可能会出错
contentType: false,
//请求地址
success: function (data) {
// msg
},
error: function (data) {
// error
}
})
});
控制器:
然后我们就可以在控制器中保存获取的文件,需要指定文件名称用storeAs方法,不需要指定保存文件的名称可使用store方法,会随机生成文件名称
//判断文件是否上传成功
if ($request->hasFile('file') && $request->file('file')->isValid()){
$request->file('file')->storeAs('/', $request->file('file')->getClientOriginalName());
return response()->json(['status' => true, 'msg' => '上传成功']); //ajax返回结果
}
公共资源路径
filesystem下的public的配置只是项目目录下的,如何使用默认配置,可以在命令行使用:
php artisan storage:link
创建软连接到public/storage目录下
但是我们既然把文件放到了项目之外,就不可以这样了,这时候就需要我们手动设置软连接,linux下使用
ln -s path1 path2
windows用户在命令行下(管理员运行,不能是powershell)
mklink /j xxx\public\storage path2
然后我们就能看到public下多出了storage文件夹,里面包含path2中的文件了,这时候我们就能通过 ip:port/storage/xxx访问了