Ajax文件上传时:Formdata、File、Blob的关系

2023-02-17 13:55:53 浏览数 (1)

Formdata接口

“Formdata”接口提供了一种表示表单数据的键值对 key/value 的构造方式,并且可以轻松的将数据通过XMLHttpRequest.send() 方法发送出去。

实现了 FormData 接口的对象可以直接在for...of(遍历属性值,for...in 则是遍历属性名)结构中使用,而不需要调用entries()返回可迭代对象(iterator) : for (var p of myFormData) 的作用和 for (var p of myFormData.entries()) 是相同的。方法、属性如下:

  1. FormData([Form])创建一个新的 FormData 对象,form这种方式创建的FormData对象会自动将form中的表单值也包含进去,包括文件内容也会被编码之后包含进去。。
  2.  append(name, value),添加一个新值到 FormData 对象内的一个已存在的键中,如果键不存在则会添加该键。 FormData.set 会使用新值覆盖已有的值,而 append() 会把新值添加到已有值集合的后面。
  3. delete() 方法会从 FormData 对象中删除指定键,即 key,和它对应的值,即 value。
  4. FormData.entries()返回一个包含所有键值对的iterator对象,遍历的值索引0为key,1为键值。
  5. FormData.get()返回在 FormData 对象中与给定键关联的第一个值。
  6. FormData.getAll()返回一个包含 FormData 对象中与给定键关联的所有值的数组。
  7. FormData.has()返回一个布尔值表明 FormData 对象是否包含某些键。
  8. FormData.keys()返回一个包含所有键的iterator对象。
  9. FormData.set()给 FormData 设置属性值,如果FormData 对应的属性值存在则覆盖原值,否则新增一项属性值。
  10. FormData.values()返回一个包含所有值的iterator对象。

如果送出时的编码类型被设为 "multipart/form-data",它会使用和表单一样的格式。

File对象、接口

  1.  File对象可以从Input元素的Files(Filelist对象)属性中获取(如files[0]),可以用于FileReader对象在本地读取文件。
  2. 还可以通过new File(),var myFile = new File(bits, name[, options]);
    1. name,表示文件名称,或者文件路径。
    2. bits,一个包含ArrayBuffer,ArrayBufferView,Blob,或者 DOMString 对象的 Array — 或者任何这些对象的组合。这是 UTF-8 编码的文件内容。
    3. options 可选,type: DOMString,表示将要放到文件中的内容的 MIME 类型。默认值为 "" 。lastModified: 数值,表示文件最后修改时间的 Unix 时间戳(毫秒)。默认值为 Date.now()。
  3. https://developer.mozilla.org/zh-CN/docs/Web/API/File
代码语言:javascript复制
var file = new File(["foo"], "foo.txt", {
  type: "text/plain",
});

下载new file() 生成的对象文件

首先创建一个a标签,href属性赋值为要下载文件对象的URL,然后调用a标签上的click()方法就可以下载file文件到本地了。

关于文件对象的URL怎么获得,这里要用到URL.createObjectURL(object)方法,参数object为一个File对象或者Blob对象,返回值就是一个UTF-16字符串,可以当作a标签的href属性值来使用。

注意:在使用完URL.createObjectURL()方法之后,要用URL.revokeObjectURL(url)来释放掉。

参数url为刚才生成的那个UTF-16字符串。详情参考https://developer.mozilla.org/zh-CN/docs/Web/API/URL/createObjectURL

代码语言:javascript复制
let file = new File([data], "fileName.obj");/*创建一个file文件*/
/*let blob = new Blob([data]);*/
/*download属性是HTML5新增的属性,也就是作用在HTML5的基础之上,他可以使a标签的href属性进行下载,download属性为下载后的文件名*/
let aTag = document.createElement('a');/*创建一个a标签*/
aTag.download = file.name;
let href = URL.createObjectURL(file);/*获取url*/
aTag.href = href;
aTag.click();
URL.revokeObjectURL(href);/*释放url*/

Blob

Blob 对象表示一个不可变、原始数据的类文件对象。它的数据可以按文本或二进制的格式进行读取,也可以转换成 ReadableStream 来用于数据操作。

Blob 表示的不一定是JavaScript原生格式的数据。File 接口基于Blob,继承了 blob 的功能并将其扩展使其支持用户系统上的文件。

参考:https://developer.mozilla.org/zh-CN/docs/Web/API/Blob

FileRaeader对象用于读取本地的文件:https://developer.mozilla.org/zh-CN/docs/Web/API/FileReader

URL.createObjectURL() 静态方法会创建一个 DOMString,其中包含一个表示参数中给出的对象的URL。这个 URL 的生命周期和创建它的窗口中的 document 绑定。这个新的URL 对象表示指定的 File 对象或 Blob 对象。参数为用于创建 URL 的 File 对象、Blob 对象或者 MediaSource 对象。​

https://developer.mozilla.org/zh-CN/docs/Web/API/URL/createObjectURL

Jquery相关操作

 serialize(),序列表表格内容为字符串。

serializeArray(),序列化表格元素 (类似 '.serialize()' 方法) 返回 JSON 数据结构数据。此方法返回的是JSON对象而非JSON字符串。需要使用插件或者第三方库进行字符串化操作。返回的JSON对象是由一个对象数组组成的,其中每个对象包含一个或两个名值对——name参数和value参数(如果value不为空的话)

上传的图片大小检测

代码语言:javascript复制
let  nImg = new Image();

nImg.src=URL.createObjectURL(file.data);
nImg.onload=function (){
     if(this.width>1440 || this.width>1080){
        layer.msg("图片宽度最大分辨率不能超过1440x1080!",{time:3000},function (){
        uppy.removeFile(file.id); /*删除选项*/
     });
 }
}

PHP上传大文件需要进行的修改

web请求php执行时间受到2方面控制,一个是php.ini的max_execution_time(要注意的是sleep,http请求等待响应的时间是不算的,这里算的是真正的执行时间),另一个是php-fpm request_terminate_timeout 设置,这个算的是请求开始n秒。

1.PHP部分

file_uploads on 是否允许通过HTTP上传文件的开关。默认为ON即是开 upload_tmp_dir – 文件上传至服务器上存储临时文件的地方,如果没指定就会用系统默认的临时文件夹 upload_max_filesize 8m 望文生意,即允许上传文件大小的最大值。默认为2M post_max_size 8m 指通过表单POST给PHP的所能接收的最大值,包括表单里的所有值。默认为8M max_execution_time 600 每个PHP页面运行的最大时间值(秒),默认30秒 max_input_time 600 每个PHP页面接收数据所需的最大时间,默认60秒 memory_limit 8m 每个PHP页面所吃掉的最大内存,默认8M

2.Nginx部分

可以选择在http{ }中设置:client_max_body_size 20m; 也可以选择在server{ }中设置:client_max_body_size 20m; 还可以选择在location{ }中设置:client_max_body_size 20m; 三者有区别 设置到http{}内,控制全局nginx所有请求报文大小 设置到server{}内,控制该server的所有请求报文大小 设置到location{}内,控制满足该路由规则的请求报文大小

send_timeout 60; fastcgi_connect_timeout 300; fastcgi_send_timeout 300; fastcgi_read_timeout 300;

实际上传不受 keepalive_timeout 时间影响,和该项配置无关,而且这个时间加长会严重影响 nginx 的并发

send_timeout , 客户端上传时网络断流后超过 60s 则停止接收接收操作,中断连接。只要持续发送数据则不会断掉

3.客户端部分

修改客户端执行上传时,限制的超时时间。

UNIAPP部分

"networkTimeout" : { "request" : 3600000, "uploadFile" : 3600000, "downloadFile" : 3600000 }

文件上传进度

Mozilla:https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest/upload

0 人点赞