前台表单文件上传

863 阅读1分钟

这是我参与11月更文挑战的第1天,活动详情查看:2021最后一次更文挑战

1. 文件上传 - 音频,图片,文本上传给服务器是二进制数据

<form action="http://localhost:8080/upload" method="POST" enctype="multipart/form-data">
<input type="text" name="user"> 
<input type="text" name="pass"> 
<input type="file" name="f">
<input type="submit" value="提交">
</form>

2. 表单三种编码类型(enctype)

enctype
application/x-www-form-urlencoded默认, key1=value1&key2=value2
multipart/form-data一般用于表单需要文件上传
text/plain ,application/json传递文本内容

3. 编码类型介绍

  1. application/x-www-form-urlencoded
  2. multipart/form-data 在表单内上传文件时(二进制流数据)
    • GET方式,会将表单中的数据(键值对)经过urlencode编码后追加到url中
    • POST方式,会将表单中的数据经过urlencode编码后放在request body 中
  3. text/plain: 纯文本
  4. text/xml : 传递xml语法格式的字符串
  5. text/html: 传递html字符串
  6. application/json : 传递序列化后的 JSON 字符串。

4. formdata -- 模拟

  1. 模拟表单提交
  2. 提交文件,监控上传进度
  3. 函数
    • set(key, value) -- 会覆盖
    • append(key, value) -- 会追加
    • get(key) getAll(key)
    • delete(key)
  4. 获取提交文件方式
    • 拖拽事件 - ev.dataTransfer.files
    • 文件组件 - oFile.files
低级浏览器不支持,可以使用swf辅助完成 -- swfuploader
let data = new FormData()
data.set(name, value)  // 如果某个 key 已经存在,set() 会直接覆盖所有该 key 对应的值

// 文件添加formdata
let oFile = document.getElementById("file")
Array.from(oFile.files).forEach(file=>{
 data .append("file", file) // 在该 key 的最后位置再追加一个值
})

// GET数据处理
let arr = []
data.forEarch((val,key)=>{
    arr.push(`${encodeURIComponent(key)}=${encodeURIComponent(val)}}`)
})
let str = arr.join("&") // key=val&key=val

xhr.open("GET", `http://localhost:8080/api?${arr.join("&")}`, true)
xhr.send()

// POST
xhr.open("POST", `/api`, true)
// xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); // ajax2.0无需设置请求头
xhr.send(data)
<!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>Document</title>
</head>
<body>
    <form>
            <input type="file" id="file" name="icon">
            <input type="text" id="user" name="user">
            <input type="button" id="btn" value="发请求">
    </form>
</body>
</html>

<script>
    //找到表单元素
    var form = document.querySelector('form');
    document.getElementById('btn').onclick = function(){

        //点击事件里我需要发一个异步请求
        //早期的ajax技术,是不支持异步上传文件的
        //在后期更新了ajax2.0版本,支持上传文件!它需要借助于一个对象,这个对象叫FormData对象
        //ajax2.0大体的步骤跟以前是一样的,区别
        
        //1. 还是要创建个请求对象
        var xhr = new XMLHttpRequest();
        
        //2. 还是要设置请求行
        xhr.open('post','data.php');
        
        //3. ajax2.0 里不需要设置请求头,它内部会自动帮你设置
        //创建一个FormData对象,并且传入一个表单
        var fm = new FormData(form);  //
        xhr.send(fm);
        xhr.onload = function(){
            console.log(xhr.responseText);
        }
    }
</script>