AJAX图片上传和验证图片格式

AJAX学习笔记(二)之活用进阶:AJAX上传图片和验证图片格式 上传图片功能就是上传文件的分支,前端最好还是验证一下是否为图片减少服务器压力和保证安全性 互联网面向全部人群害人之心不可有,防人之心不可无,开发者都忌讳有人走上传文件的漏洞借以控制服务器的,所以上传文件这一区域我觉得最安全还是前后台一起都要验证,非法操作的就禁他ip地址到特定的时间才能上传。 还有最好用计时器控制用户在某段时间内上传图片的次数,减少服务器压力提高性能。 一 . 首先我们要了解 FormData 对象 FormData 接口的构造方式,经过它的数据可以使用 XMLHttpRequest.send() 方法送出, 本接口和此方法都相当简单直接。如果送出时的编码类型被设为 “multipart/form-data”, 它会使用和表单一样的格式。 属性 介绍 FormData.append() 向 FormData 中添加新的属性值, **FormData **对应的属性值存在也不会覆盖原值,而是新增一个值,如果属性不存在则新增一项属性值 。 FormData.delete() 从 FormData 对象里面删除

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·

text
<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路径中就可以知道图片替换成功就代表上传成功了~

text
$('.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为例子)·

text
/**
 *@图片上传
 *@@
 */
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>";
  }
}