以上两种方案都可以实现传统form提交下的局部刷新功能, 不过方案一需要单独维护iframe表单, 所以我呢一般采用方案二, 而且兼容性都可以达到IE9(虽然现在来说兼容IE浏览器意义不大, 但是还是要了解一下)
1.2 ajax + formData方案
在XHR盛行之后,我们可以轻松使用ajax来实现异步请求了, 对于文件上传, 我们也可以更灵活的使用ajax和formData来实现, 逐渐脱离了对原生form表单的依赖.
FormData 对象用以将数据编译成键值对,以便用XMLHttpRequest来发送数据。其主要用于发送表单数据,但亦可用于发送带键数据(keyed data),而独立于表单使用。如果表单enctype属性设为multipart/form-data ,则会使用表单的submit()方法来发送数据,从而,发送数据具有同样形式。
我们先来看一个简单的使用formData上传文件的例子:
let formData = new FormData();
// HTML 文件类型input,由用户选择
formData.append("userfile", fileInputElement.files[0]);
let request = new XMLHttpRequest();
request.open("POST", "http://http://io.nainor.com/h5/form");
request.send(formData);
以上短短5行代码就实现了将文件通过formData的方式上传给了服务器, 是不是很简单呢? 笔者之前的文章 基于react/vue开发一个专属于程序员的朋友圈应用就采用了该方案, 感兴趣的可以学习研究一下.
如果要实现多文件上传也非常简单, 这里我们以axios为例, 具体实现如下:
const formData = new FormData()
for(let i=0; i< files.length; i++) {
formData.append(`file_${i+1}`, files[i].file)
}
axios({
method: 'post',
url: '/files/upload/tx',
data: formData,
headers: {
'Content-Type': 'multipart/form-data'
}
});
这里要注意多文件上传要在请求的http header中设置 Content-Type 为 multipart/form-data . 当然大家还可以基于以上原理实现更符合自身业务需求的文件上传组件, 比如预览, 限流等.
1.3 第三方组件实现
为了更高效快速的开发业务, 我们有时候也可以选择第三方比较成熟的方案, 比如antd的upload组件, 比如element ui的上传组件, 这里笔者总结了几个比较好用且强大的方案, 大家可以感受一下:
- antd/element 的 upload 组件
- FilePond 可以上传任何内容,并能够优化图像以加快上传速度,同时提供顺畅的用户体验
- Web Uploader 百度WebFE(FEX)团队开发的一个简单的以HTML5为主,FLASH为辅的现代文件上传组件
- vue-simple-uploader 基于vue的强大美观的文件上传组件
我们可以通过上述提供的第三方组件库, 结合自己服务端的配置,就可以轻松实现强大的上传组件了.
2. 将裁剪功能集成到图片上传组件
对于图片上传组件来说, 我们往往不能确定用户上传的到底是什么, 所以我们要提前约束, 比如说对图片大小, 图片格式, 图片比例等进行限制以符合我们的业务标准. 图片大小和图片格式的限制非常好实现, 但是对于图片比例, 这个我们不能期望用户自己来处理, 因为这样会极大的增加用户使用网站的负担, 所以我们可以提供一种功能, 让用户在线切图. 如下图所示:
以上截图来自于H5-Dooring在线编辑器的图片上传组件, 在用户上传之后我们会出现图片裁切界面, 我们会指定图片的比例, 让用户自由裁切.
笔者将基于antd的upload组件配合antd-img-crop来带大家实现在线切图功能. 具体代码实现如下:
import React, { useState } from 'react';
import { Upload } from 'antd';
import ImgCrop from 'antd-img-crop';
const Demo = () => {
const [fileList, setFileList] = useState([
{
uid: '-1',
name: 'image.png',
status: 'done',
url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
},
]);
const onChange = ({ fileList: newFileList }) => {
setFileList(newFileList);
};
const onPreview = async file => {
let src = file.url;
if (!src) {
src = await new Promise(resolve => {
const reader = new FileReader();
reader.readAsDataURL(file.originFileObj);
reader.onload = () => resolve(reader.result);
});
}
const image = new Image();
image.src = src;
const imgWindow = window.open(src);
imgWindow.document.write(image.outerHTML);
};
return (
{fileList.length < 5 && '+ Upload'}
);
};
ReactDOM.render(, mountNode);
以上只是一个基本的裁切并上传图片的例子, 当然antd-img-crop还提供了更多灵活的配置来方便我们设计更灵活强大的裁切效果. 当然我们还可以使用react-cropper来实现, 它提供了更灵活的裁切控制以及裁切实时预览功能, 如下图所示:
3. 内容平台/可视化平台下的图片自治
对于内容平台或者可视化平台而且, 单纯的上传图片还不能满足用户的需求, 因为内容/可视化平台更加注重图片的选择和使用, 对图片要求也很高, 用户自己上传毕竟资源有限, 往往不能达到用户对内容发布的需求或者可视化设计的需求, 所以往往在这类平台中会提供图片素材库这一功能, 用户可以在素材库中搜索海量图片以满足自己的需求, 而往往这样, 才更能留住用户, 增加用户粘性.
基于以上场景产品经理往往会提出这样的需求: 能不能提供可选方案, 用户既能自己上传图片, 也能使用我们提供的图片库资源呢? 这个时候有经验的前端往往会说一句: 安排!
在设计该功能之前我们往往要先参考其他已有实现, 这里我们举几个例子, 如下图所示:
一、网安学习成长路线图
网安所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。
二、网安视频合集
观看零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。
三、精品网安学习书籍
当我学到一定基础,有自己的理解能力的时候,会去阅读一些前辈整理的书籍或者手写的笔记资料,这些笔记详细记载了他们对一些技术点的理解,这些理解是比较独到,可以学到不一样的思路。
四、网络安全源码合集+工具包
光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。
五、网络安全面试题
最后就是大家最关心的网络安全面试题板块
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!