php - 上传前验证文件的扩展名和大小
问题描述
我试图制作一个文件上传器,它应该能够上传 mimes,即:.jpg, .jpeg, .pdf, .bmp, .png, .doc & .docx
。我还提出了一个请求规则,如下所示:
StoreFileRequest.php
public function rules()
{
'files.*' => [
'mimes:jpg,jpeg,pdf,bmp,png,doc,docx',
'max:20000',
],
}
控制器
use App\Http\Requests\Backend\StoreFileRequest;
public function store(StoreFileRequest $request)
{
if($request->hasFile('files'))
{
foreach ($files as $file) {
//file Mime type
$fileMimeType=$file->getClientMimeType();
//change filename to laravel generated name using above extention
$filename=$file->hashName();
//upload file
$path=$file->storeAs('public/user-existing-health-reports/'.auth()->user()->uuid,$filename);
}
}
}
刀
{!! Form::file('files[]',
array('class' => 'form-control btn btn-file ',
'accept'=>'.jpg, .jpeg, .pdf, .bmp, .png, .doc, .docx',
'multiple',
'required',
)) !!}
尽管有上面的验证规则,让我们假设如果我尝试上传一个.zip
& 还有一个.rar
在1GB
. 该文件首先被上传,这需要相当长的时间,然后在验证后引发错误。
我的问题:我需要在用户单击提交按钮时验证文件扩展名和大小,然后再上传文件以通过验证器进行验证。
解决方案
一旦收到请求数据,验证规则和请求数据验证就会在服务器上发生。
所以很自然,即使您尝试上传 2GB 文件或 zip 文件,它也必须先到达服务器,然后才能根据验证规则进行验证。
您还必须在前端实现一些验证以防止此类问题。
例如,您可以检查在前端上传的文件的 mime 类型和大小(通过 javascript),并且只有当它在前端通过验证时才允许使用上传的文件向服务器发出请求。
但是,永远不要只依赖前端的验证。服务器级别的验证是必须的。
例如验证上传的文件大小不超过 20MB
function isValidSize(file) {
const errors = [];
const maxUploadSizeInBytes = 20 * 1024 * 1024;
let valid = true;
if (file.size > maxUploadSizeInBytes) {
valid = false;
let sizeInKb = maxUploadSizeInBytes / 1024;
let sizeForHumans = sizeInKb < 1024
? `${sizeInKb} KB`
: `${sizeInKb / 1024} MB`;
this.errors.push(
`The file exceeds the maximum allowed size of ${sizeForHumans}`
);
}
return valid;
}
根据允许的 mime 类型验证上传文件的 mime 类型的功能
isValidType(file) {
const errors = [];
let acceptedMimes = "jpg,jpeg,png,webp"
.trim()
.split(",")
.map(type => `image/${type}`);
let valid = true;
if (!acceptedMimes.includes(file.type)) {
valid = false;
let phrase = acceptedMimes.replace(/,/g, " or ");
this.errors.push(
`The file type is not allowed. Please upload ${phrase} file.`
);
}
return valid;
}
服务器(后端)的验证是必须的
前端验证是为了更好的用户体验和节省一些不必要的网络请求推荐阅读
- java - 我在我的 android 应用程序中遇到地理定位问题
- python - 在控制台中执行时python纸浆脚本错误
- jquery - 在不重新加载页面的情况下聆听另一个用户帐户上一个用户的更改的最佳方法?
- php - 创建连接脚本:我应该使用 unset 吗?
- python - 从 python 3.8.5 降级到 python 3.6
- ruby-on-rails - 如何将 Rails master.key 传递到 Heroku 上的 Docker 容器中?
- python - 无法安装张量网
- grapesjs - 如何定义组件掉落的确切位置?
- python - The Foundry NUKE 10.5v5 – 重新打开脚本时回调不起作用
- python - 在导入模块之前测试类是否在模块中