AJAX学习笔记(二)之活用进阶:AJAX上传图片和验证图片格式
上传图片功能就是上传文件的分支,前端最好还是验证一下是否为图片减少服务器压力和保证安全性
互联网面向全部人群害人之心不可有,防人之心不可无,开发者都忌讳有人走上传文件的漏洞借以控制服务器的,所以上传文件这一区域我觉得最安全还是前后台一起都要验证,非法操作的就禁他ip地址到特定的时间才能上传。
还有最好用计时器控制用户在某段时间内上传图片的次数,减少服务器压力提高性能。
一 . 首先我们要了解 FormData 对象
FormData 接口的构造方式,经过它的数据可以使用 XMLHttpRequest.send() 方法送出, 本接口和此方法都相当简单直接。如果送出时的编码类型被设为 “multipart/form-data”, 它会使用和表单一样的格式。
| 属性 | 介绍 |
|---|---|
| FormData.append() | 向 FormData 中添加新的属性值, **FormData **对应的属性值存在也不会覆盖原值,而是新增一个值,如果属性不存在则新增一项属性值 。 |
| FormData.delete() | 从 FormData 对象里面删除一个键值对 |
| FormData.entries() | 返回一个包含所有键值对的 iterator对象 |
| FormData.get() | 返回在 FormData 对象中与给定键关联的第一个值 |
| FormData.getAll() | 返回一个包含 FormData 对象中与给定键关联的所有值的数组 |
| FormData.has() | 返回一个布尔值表明 FormData 对象是否包含某些键 |
| FormData.keys() | 返回一个包含所有键的 iterator对象 |
| FormData.set() | 给 FormData 设置属性值,如果 FormData 对应的属性值存在则覆盖原值,否则新增一项属性值 |
| FormData.values() | 返回一个包含所有值的 iterator对象 |
二 . 设置上传图片按钮
·HTML·
<div class="test_box " name="img" style="width:auto;border: none;box-shadow: none;">
<div class="img_box">
<img src="__ROOT__/public/admin/image/123.jpg" class="_img" name="picture">
</div>
<span add><i class="add iconplus-circle-fill"></i>
<input type="file" id="upimg" accept="image/jpeg,image/x-png,image/gif" multiple style="display: none">
</span>
</div>
这里是一个图标点击等于input上传file的点击事件目的就是让上传按钮看的更好看
· JS ·
··· 要点 ···
··第9行ojb[0].file[0]获取file input中file对象。
··toLowerCase()方法用于把字符串转换为小写。
··第10行lastIndexOf 是从右向左查某个指定的字符串在字符串中最后一次出现的位置(也就是从后往前查)
··第11行substring() 方法用于提取字符串中介于两个指定下标之间的字符。
··第20行form.append插入key :value格式的js键值对类似于插入数组
··第21~23行先判断flie对象文件或图片上传多少个,我现在用的file ajxa图片上传可以支持多个文件的 然后 把flie对象放进formData对象中
··!注意 !
processData: false
contentType: false
这个两个要加上不然会报错
processData设置为false。因为data值是FormData对象,不需要对数据做处理。jq默认为 true
contentType设置false 。我用的后端是tp5 不设置默认识别为application/json 然后formdata对象数据不属于json,false就是不注重识别传的数据的类型。
··ajax后就获取回后端data数据返回到页面img src路径中就可以知道图片替换成功就代表上传成功了~
$('.up.iconicon-test').off().on('mousedown', function () { //off()防止一次提交变多次提交
$('#ajax_img').click(); //一个图标dom点击等于input上传file的点击事件
$('.choice-youneedimg').off().on('change', upload)
function upload() {
//验证图片
var form = new FormData(); //定义FormData对象
var ojb = $('#ajax_img')
function check_img() {
let img_src = ojb[0].files[0]['name'].toLowerCase();
let index = img_src.lastIndexOf('.');
let check_img = img_src.substring(index)
if (check_img == '.png' || check_img == '.gif' || check_img == '.jpg' || check_img == '.jpeg') {
return true;
} else {
return false;
}
}
if (check_img() == true) {
form.append('id', '112');
for (let i = 0; i < ojb[0].files.length; i++) {
form.append('file', ojb[0].files[i]);
}
console.log(form.get('file')['name'])
//这里可以用ajax上传图片到后台然后图片路径返回前台
$.ajax({
url: e.img_url,
type: "post",
data: form,
processData: false,
contentType: false,
success: function (data) {
alert(data['success'])
$('._img').attr('src', /public/ + data['src']); //修改路径
td.eq(i).find('.img').attr('src', /public/ + data['src']);
}
})
} else {
alert('请选择上传图片文件');
}
}
})
· PHP (TP为例子)·
/**
*@图片上传
*@@
*/
public function image(){
if(Request::instance()->isajax()){
$id=Request::instance()->post();
$file=request()->file('file');
if(true!==$this->validate(['image'=>$file],['image'=>'require|image'],['image'=>'max:20485760'])){
return('请选择图像文件或者文件大小大于2m');
}
$info=$file->move(ROOT_PATH.'public'.DS.'uploads'.DS.'article');
if($info){
//成功上传后获取上传信息
//存入相对路径/upload/日期/文件名
//getSaveName是输出文件的位置以及文件名。系统会自动穿件以时间为名的文件夹,然后输出文件夹的名字和图片的名字。
$data=DS.'uploads'.DS.'article'.DS.$info->getSaveName();
//修改到数据库
//判断id是否为空为空就跳到添加新最新id
if($id['id']==null){
$time=date('Y-m-d H:i:s',time());
Db::table('my_article')->insert(['picture'=>$data,'join_time'=>$time]);
}else{
$_s=Db::table('my_article')->where($id)->setField([
'picture'=>$data
]);
}
return array('success'=>"上传成功图片",'src'=>$data,);
}else{
//上传失败获取错误信息
echo $file->getError();
}
}else{
echo "<script>location='/admin/login'</script>";
}
}