JS 中使用 FormData 上传文件 图片的方法 JQ 的 input file change 事件只触发一次

发布于 2022-11-02 21:04:52 字数 19521 浏览 125 评论 0

上传文件设置 formData

var formData = new FormData();
formData.append("file", $("#postfile")[0].files[0]);

防止浏览器缓存页面或请求结果

public class NoCacheFilter implements Filter {
    @Override  
    public void destroy(){  
    }
  
    @Override  
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {  
        HttpServletResponse response = (HttpServletResponse)resp;  
  
        response.setDateHeader("Expires", -1);  
        response.setHeader("Cache_Control", "no-cache");  
        response.setHeader("Pragma", "no-cache");  
          
        response.setHeader("Access-Control-Allow-Origin", "*");     //允许跨域请求  
          
        chain.doFilter(req, resp);  
    }

    @Override  
    public void init(FilterConfig arg0) throws ServletException {  
    }  
}  

默认情况下,跨源请求不提供凭据(cookie、HTTP 认证及客户端SSL证明等)。通过将 withCredentials 属性设置为 true,可以指定某个请求应该发送凭据。如果服务器接收带凭据的请求,会用下面的 HTTP 头部来响应。

其实就是我们刚才设置的第二条配置。

虽然设置了 widthCredentials 为 true 的请求中会包含远程域的所有 cookie,但这些 cookie 仍然遵循同源策略,所以外域是访问不了这些 cookie 的,现在我们就可以安全地跨域访问了。

一、input:file 属性

属性值有以下几个比较常用:

  • accept:表示可以选择的文件 MIME 类型,多个 MIME 类型用英文逗号分开,常用的 MIME 类型见下表。
  • multiple:是否可以选择多个文件,多个文件时其value值为第一个文件的虚拟路径。

1、accept

只能选择 png 和 gif 图片

<input type="file" accept="image/png,image/gif" name="file" />

2、multiple

多文件上传

<input type="file" multiple="multiple" name="file" />

3、常用 MIME 类型

*.3gpp  audio/3gpp, video/3gpp
*.ac3  audio/ac3
*.asf     allpication/vnd.ms-asf
*.au       audio/basic
*.css       text/css
*.csv       text/csv
*.doc  application/msword  
*.dot  application/msword  
*.dtd  application/xml-dtd  
*.dwg  image/vnd.dwg  
*.dxf    image/vnd.dxf
*.gif      image/gif  
*.htm  text/html  
*.html  text/html  
*.jp2      image/jp2  
*.jpe     image/jpeg
*.jpeg  image/jpeg
*.jpg      image/jpeg  
*.js     text/javascript, application/javascript  
*.json  application/json  
*.mp2  audio/mpeg, video/mpeg  
*.mp3  audio/mpeg  
*.mp4  audio/mp4, video/mp4  
*.mpeg  video/mpeg  
*.mpg  video/mpeg  
*.mpp  application/vnd.ms-project  
*.ogg  application/ogg, audio/ogg  
*.pdf  application/pdf  
*.png  image/png  
*.pot  application/vnd.ms-powerpoint  
*.pps  application/vnd.ms-powerpoint  
*.ppt  application/vnd.ms-powerpoint  
*.rtf      application/rtf, text/rtf  
*.svf       image/vnd.svf  
*.tif     image/tiff  
*.tiff     image/tiff  
*.txt       text/plain  
*.wdb  application/vnd.ms-works  
*.wps  application/vnd.ms-works  
*.xhtml  application/xhtml+xml  
*.xlc    application/vnd.ms-excel  
*.xlm  application/vnd.ms-excel  
*.xls       application/vnd.ms-excel  
*.xlt    application/vnd.ms-excel  
*.xlw    application/vnd.ms-excel  
*.xml  text/xml, application/xml  
*.zip      aplication/zip  
*.xlsx   application/vnd.openxmlformats-officedocument.spreadsheetml.sheet

三、AJAX上传文件

在说到 ajax 上传文件,之前的文章也有说过。ajax 上传的时候,需要获得 input:file 选择的文件(可能为多个文件),获取其文件列表为:

// input标签的files属性
document.querySelector("#fileId").files
// 返回的是一个文件列表数组
获得的文件列表,然后遍历插入到表单数据当中。即:
// 获得上传文件DOM对象
var oFiles = document.querySelector("#fileId");

// 实例化一个表单数据对象
var formData = new FormData();

// 遍历图片文件列表,插入到表单数据中
for (var i = 0, file; file = oFiles[i]; i++) {
  // 文件名称,文件对象
  formData.append(file.name, file);
}
获得表单数据之后,就可以用ajax的POST上传。
// 实例化一个AJAX对象
var xhr = new XMLHttpRequest();
xhr.onload = function() {
  alert("上传成功!");
}
xhr.open("POST", "upload.php", true);

// 发送表单数据
xhr.send(formData);

上传到服务器之后,获取到文件列表为:

Array
(
[jpg_jpg] => Array
  (
    [name] => jpg.jpg
    [type] => image/jpeg
    [tmp_name] => D:\xampp\tmp\phpA595.tmp
    [error] => 0
    [size] => 133363
  )

[png_png] => Array
  (
    [name] => png.png
    [type] => image/png
    [tmp_name] => D:\xampp\tmp\phpA5A6.tmp
    [error] => 0
    [size] => 1214628
  )
)

在服务端循环遍历这个数组就可以上传文件了。

<input type="file" accept="text/plain" multiple="multiple" />

function postFile() { //判断是否有选择上传文件
  var imgPath = $("#postfile").val();
  if(imgPath == "") {
    $(".poststate").text("请选择上传的文本文件,以.txt后缀结尾!").css("color", "blue");
    return;
  }

  var strExtension = imgPath.substr(imgPath.lastIndexOf('.') + 1); //判断上传文件的后缀名
  if(strExtension != 'txt') {
    $(".poststate").text("请选择上传的文本文件,以.txt后缀结尾!").css("color", "blue");
    return;
  }
  var formData = new FormData();
  formData.append("file", $("#postfile")[0].files[0]);
  console.log(postfile.files[0]);
  $.ajax({
    contentType: "multipart/form-data",
    url: "s3/operationmsg/upload",
    type: "POST",
    data: formData,
    dataType: "text",
    processData: false,
    contentType: false,
    cache: false,
    beforeSend: function() {
      $(".poststate").text("正在努力上传中,请稍后!").css("color", "green");
    },
    success: function(data) {
      var reObj = JSON.parse(data);
      if(reObj.content) {
        $(".poststate").text('"' + reObj.content.fileName + '"' + "上传成功!").css("color", "green");
      }
    },
    error: function(XMLHttpRequest, textStatus, errorThrown) {
      $(".poststate").text("上传失败,请检查网络后重试!").css("color", "red");;
    }
  });
}

$("#postfile").on('change', function() { //文件上传
  $(".poststate").text("请选择上传以.txt后缀结尾的文本文件!").css("color", "blue");
  postFile();
});

var fileInfo =$('#inputfile').prop('files')[0];

var fd = new FormData();
fd.append("xxxx", fileInfo);
$.ajax({
  url: "xxxx.htm",
  type: "POST",
  processData: false, 
  contentType: false, 
  dataType: 'json', 
  data: fd, 
  success:function(data){},
  error:function(data){}
});

关于 JQuery 上传图片 input file change 事件只触发一次问题:

$(document).on('change onpropertychange',"#imgUrl", function() { //文件上传
  var file = this.files[0];  
  console.log(file);
  if((file.size / 1024).toFixed(0)>300){
   $.alert({
    title: '提示!',
    content: "图片大小为:"+(file.size / 1024).toFixed(0)+"kb,要求不能大于300kb",
    confirm: function(){
      
    }
   });
   return;
  };
  //读取图片数据
  var reader = new FileReader();
  reader.onload = function (e) {
    var data = e.target.result;
    //加载图片获取图片真实宽度和高度
    var image = new Image();
    image.onload=function(){
     var width = image.width;
     var height = image.height;
     if(width=="590"&&height=="824"){
       postFile();
       $('#imgUrl').replaceWith('<input class="postfile" type="file" multiple="multiple">');
     }else{
      $.alert({
       title: '提示!',
       content: "图片宽高不符合590*824!",
       confirm: function(){
        
       }
      });
      $('#imgUrl').replaceWith('<input class="postfile" type="file" multiple="multiple">');
     }
    };
    image.src= data;
  };
  reader.readAsDataURL(file);
});

$(document).on('change onpropertychange', "#postfile",function() { //这里要用事件委派b   
$(".poststate").text("请选择上传以.txt后缀结尾的文本文件!").css("color", "blue");
postFile();
$('#postfile').replaceWith('<input type="file" accept="text/plain" multiple="multiple" />');
});

function postFile() { //判断是否有选择上传文件
  var imgPath = $("#postfile").val();
  if(imgPath == "") {
   $(".poststate").text("请选择上传的文本文件,以.txt后缀结尾!").css("color", "blue");
   return;
  }

  var strExtension = imgPath.substr(imgPath.lastIndexOf('.') + 1); //判断上传文件的后缀名
  if(strExtension != 'txt') {
   $(".poststate").text("请选择上传的文本文件,以.txt后缀结尾!").css("color", "blue");
   return;
  }
  var formData = new FormData();
  formData.append("file", $("#postfile")[0].files[0]);
  //console.log(postfile.files[0]);
  $.ajax({
   contentType: "multipart/form-data",
   url: "xxxx/xxxxx/xx",
   type: "POST",
   data: formData,
   dataType: "text",
   processData: false,
   contentType: false,
   cache: false,
   beforeSend: function() {
    $(".poststate").text("正在努力上传中,请稍后!").css("color", "blue");
   },
   success: function(data) {
    var reObj = JSON.parse(data);
    if(reObj.status=="0"){
      
      if(reObj.content) {
       $.alert({
        title: '提示:',
        backgroundDismiss: true, 
        content: '上传文件成功!'
       });
       $(".poststate").text('"' + reObj.content.fileName + '"' + "上传成功!").css("color", "blue");
       PostObj.pubS3FileUrl = reObj.content.url;
      }else {
       $.alert({
        title: '提示:',
        backgroundDismiss: true,
        content:  reObj.message
       });
       $(".poststate").text("");
      }
    }else{
      PostObj.pubS3FileUrl="";
      $.alert({
        title: '提示:',
        backgroundDismiss: true,
        content:  reObj.message
       });
       $(".poststate").text(reObj.message);
      }
   },
   error: function(XMLHttpRequest, textStatus, errorThrown) {
    $(".poststate").text("上传失败,请检查网络后重试!").css("color", "red");;
   }
  });
}

用来把文件读入内存,并且读取文件中的数据。FileReader 接口提供了一个异步 API,使用该 API 可以在浏览器主线程中异步访问文件系统,读取文件中的数据。到目前文职,只有 FF3.6+ 和 Chrome6.0+ 实现了 FileReader 接口。

1、FileReader 接口的方法

FileReader 接口有4个方法,其中3个用来读取文件,另一个用来中断读取。无论读取成功或失败,方法并不会返回读取结果,这一结果存储在 result 属性中。

readAsBinaryStringfile 将文件读取为二进制编码
readAsTextfile,[encoding] 将文件读取为文本
readAsDataURLfile 将文件读取为 DataURL
abort(none) 终端读取操作

2、FileReader 接口事件

FileReader 接口包含了一套完整的事件模型,用于捕获读取文件时的状态。

onabort 中断
onerror 出错
onloadstart 开始
onprogress 正在读取
onload 成功读取
onloadend 读取完成,无论成功失败

上传图片预览:

<!DOCTYPE html>
<html>

  <head>
    <meta charset="utf-8">
    <title></title>
    <style type="text/css">
      * {
        padding: 0;
        margin: 0;
      }
      
      .container {
        width: 800px;
        margin: 100px auto;
      }
      
      .imgs {
        width: 300px;
        height: 300px;
      }
      
      .imgs img {
        width: 100%;
      }
    </style>
  </head>

  <body>
    <div class="container">
      <input type="file" name="file" value="上传" />
      <div class="imgs">
        <img src="" />
      </div>
      <div class="imgs">
        <img src="" />
      </div>
      <div class="imgs">
        <img src="" />
      </div>
      <div class="imgs">
        <img src="" />
      </div>
    </div>
    <script type="text/javascript">
      var fe = document.getElementById("file");
      var img = document.getElementById("preImg");
      var img1 = document.getElementById("preImg1");
      var img2 = document.getElementById("preImg2");
      var img3 = document.getElementById("preImg3");
      fe.onchange = function() {
        var reader = new FileReader();
        var _file = this.files[0];
        console.log("reader");
        console.log(reader);
        //  建议去输出下这3个东西 仔细看看就明白了
        console.log("this.files");
        console.log(this.files);
        console.log("_file");
        console.log(_file);
        reader.readAsDataURL(_file); //这个是很重要的一步  讲读取到的文件编码成DataURL 否则不能用
        console.log("reader");
        console.log(reader);
        reader.onload = function() {
          img.setAttribute('src', this.result);
        };

      }
    </script>
  </body>

</html>

<!DOCTYPE html>
<html>

  <head>
    <meta charset="UTF-8">
    <title></title>
  </head>

  <body>
    <script type="text/javascript">
      var result = document.getElementById("result");
      var file = document.getElementById("file");

      //判断浏览器是否支持FileReader接口  
      if(typeof FileReader == 'undefined') {
        result.InnerHTML = "<p>你的浏览器不支持FileReader接口!</p>";
        //使选择控件不可操作  
        file.setAttribute("disabled", "disabled");
      }

      function readAsDataURL() {
        //检验是否为图像文件  
        var file = document.getElementById("file").files[0];
        if(!/image\/\w+/.test(file.type)) {
          alert("看清楚,这个需要图片!");
          return false;
        }
        var reader = new FileReader();
        //将文件以Data URL形式读入页面  
        reader.readAsDataURL(file);
        reader.onload = function(e) {
          var result = document.getElementById("result");
          //显示文件  
          result.innerHTML = '<img src="" alt="" />';
        }
      }

      function readAsBinaryString() {
        var file = document.getElementById("file").files[0];
        var reader = new FileReader();
        //将文件以二进制形式读入页面  
        reader.readAsBinaryString(file);
        reader.onload = function(f) {
          var result = document.getElementById("result");
          //显示文件  
          result.innerHTML = this.result;
        }
      }

      function readAsText() {
        var file = document.getElementById("file").files[0];
        var reader = new FileReader();
        //将文件以文本形式读入页面  
        reader.readAsText(file);
        reader.onload = function(f) {
          var result = document.getElementById("result");
          //显示文件  
          result.innerHTML = this.result;
        }
      }
    </script>
    <p>
      <label>请选择一个文件:</label>
      <input type="file" />
      <input type="button" value="读取图像" onclick="readAsDataURL()" />
      <input type="button" value="读取二进制数据" onclick="readAsBinaryString()" />
      <input type="button" value="读取文本文件" onclick="readAsText()" />
    </p>
    <div name="result"></div>
  </body>
</html>

上传文件预览:

准备上传

<!DOCTYPE html>
<html lang="en">

  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>文件上传</title>
    <link rel="stylesheet" href="http://cdn.bootcss.com/bootstrap/3.2.0/css/bootstrap.min.css">
    <script src=""></script>
    <style>
      body,
      html {
        margin: 0 auto;
      }
      
      .up-header {
        width: 600px;
        text-align: center;
      }
      
      .up-content {
        min-height: 200px;
        border: 1px solid #CCCCCC;
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;
        background-color: #FAFAFA;
        color: #999;
        font-size: 20px;
        text-align: center;
      }
      
      .up-area {
        border: 2px dashed #ccc;
        margin: 10px 20px 20px 20px;
        width: 300px;
        min-height: 200px;
        line-height: 100px;
        background-color: #fff;
      }
      
      .list-group {
        margin: 0px auto;
        ;
        width: 200px;
        min-height: 100px;
        padding: 10px;
      }
      
      img {
        max-width: 100%;
      }
      
      .btn {}
      .close {
        margin-left: 550px;
        margin-top: -20px;
      }
    </style>
  </head>
  <body>
    <header class="page-header">
      <!-- 头部显示 -->
      <div class="container upload ">
        <div class="up-header center-block">
          <h2>文件上传——两种形式</h2>
          <div class="input-group" style="width:600px; display:flex;">
            <input type="text" class="form-control" placeholder="在此处粘贴图片网址">
            <button type="button" class="btn btn-primary">上传图片</button>
          </div>
        </div>
        <div class="row">
          <!-- 拖拽图片到这来 -->
          <div class="col-md-5 col-md-offset-1 up-content  dragFile">
            <p style="margin-top:10px;">拖拽图片到这里哟</p>
            <div class="up-area">
              <input type="file" style="display:none;" name="fileDragselect" multiple>
              <div class="row">
                <ul class="list-group clearfix list-drag">
                </ul>
              </div>
            </div>

          </div>
          <!-- 点击按钮上传文件 -->
          <div class="col-md-5 up-content btnFile">
            <div class="btn">
              <button type="button" class="btn btn-success"> 本地上传文件</button>
              <input type="file" style="display:none;" name="fileselect" multiple>
            </div>
            <div class="up-area">
              <div class="row">
                <ul class="list-group clearfix list-btn">
                </ul>
              </div>
            </div>
          </div>
        </div>

      </div>
    </header>

    <script type="text/javascript">
      //点击本地上传文件
      $('#btn').click(() => {
        $('#fileInput').click();
      })
      $('#fileInput').change((event) => {
        var files = event.target.files;
        appendFile(files, '.list-btn');
      })
      //拖拽上传文件 在页面进行预览 上传form用到ajax
      const dragbox = document.querySelector('.dragFile');
      dragbox.addEventListener('dragover', function(e) {
        e.preventDefault(); // 必须阻止默认事件
      }, false);
      dragbox.addEventListener('drop', function(e) {
        e.preventDefault(); // 阻止默认事件
        var files = e.dataTransfer.files; //获取文件
        appendFile(files, '.list-drag')
        // code
      }, false);

      function appendFile(files, listName) {
        for(file of files) {
          let url = window.URL.createObjectURL(file);
          let liStr = `
                <li class="list-group-item">
                  <div>
                    <img src="" alt="文件" />
                  </div>
                </li>
              `;
          $(listName).append(liStr);
        }
      }
    </script>
  </body>
</html> 

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

文章
评论
26 人气
更多

推荐作者

櫻之舞

文章 0 评论 0

弥枳

文章 0 评论 0

m2429

文章 0 评论 0

野却迷人

文章 0 评论 0

我怀念的。

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文