重拾cgi——文件上传和cgicc

简介:

html中上传文件,只需要表单里面放一个input type=file即可,如果要使用ajax异步上传(下文基于jquery),就需要注意几点(以下操作,部分需要基于html5定义的api):

1、页面上创建一个input元素,type是file。如果一个input需要支持选择多个文件,在标签中增加属性:multiple=”multiple”。(注意,这需要浏览器支持html5,具体文档可以见

2、获取这个元素绑定的已上传文件
[cce lang=”javascript”]
var files = document.getElementById(‘xxx’).files;
[/cce]
先获取元素,通过读取元素的files属性,获取所有已经选择的文件。

3、组装formdata,因为上传文件可能会比较大,所以即使支持多选文件,这里还是分成不同的请求发送。
[cce lang=”javascript”]
for(var i=0;i<array.length;i++) {
var file = files[index];
var formData = new FormData();
formData.append("file", file);
formData.append("id", i+1);
}
[/cce]
这里将每个文件单独组装成一个formdata,里面包含文件内容和一个id。

4、通过jquery发起post请求:
[cce lang=”javascript”]
$.ajax({
type: 'POST',
url: "file/new",
data: formData,
async: true,
cache: false,
processData: false,
contentType: false,
xhr: function() {
myXhr = $.ajaxSettings.xhr();
if(myXhr.upload){
myXhr.upload.addEventListener('progress',progressHandlerFunction, false);
}
return myXhr;
},
success: function(data){
if(!data.result) {
progressTag.remove();
$("#" + index).after($('<span style="color:red">'+data.msg+'</span>'));
}
}
});
[/cce]
其中的xhr部分稍后会提到,这里还有两个需要特别注意的地方。首先是processData属性,必须设置为false,其次是contentType必须设置为false。其他后端不清楚,cgicc在处理文件上传(既multipart方式post的时候),必须从http头中读取Content-Disposition属性,只有在jquery里面设置了前面提到的两个属性,才能正确的按照标准协议进行封装,让cgicc读取到正确的内容分隔字符串。

5、锦上添花,增加进度条
[cce lang=”javascript”]
var progressTag = $("<progress/>", {
value: 0,
min: 0,
max: file.size
});
$("#" + index).after(progressTag);

function progressHandlerFunction(evt) {
if (evt.lengthComputable) {
progressTag.attr("max", evt.total);
progressTag.attr("value", evt.loaded);
}
}
[/cce]
这里通过jquery动态的增加了一个progress标签(html5中新增),然后定义了一个handler。之前jquery的ajax函数中看见了,通过获取原生xhr对象,在upload事件上增加handler函数回调,在上传的同时,将具体进度反馈给用户。当然,如果需要,这里也可以绑定download事件。

6、cgicc处理文件
cgicc处理文件和普通表单元素类似,唯一的区别是需要通过cgi.getFile函数来获取,而不是cgi.getElement。
[cce lang=”cpp”]
cgicc::form_iterator idIter = cgi.getElement("id");
cgicc::file_iterator fileIter = cgi.getFile("file");
if(idIter == cgi.getElements().end())
{
//handle error
}
int id = (int)idIter->getIntegerValue();

if(fileIter == cgi.getFiles().end())
{
//handle error
}
std::ofstream of(boost::lexical_cast<std::string>(id));
fileIter->writeToStream(of);
[/cce]
这里忽略了错误处理,通过获取表单元素,作为文件名,直接将文件通过标准库文件输出流ofstream写到磁盘上。

这样,就完成了从页面上选择文件,到后台保存的简单流程。

目录
相关文章
|
Ubuntu
避坑指南之Samba4在Ubuntu20.04 编译安装指南
避坑指南之Samba4在Ubuntu20.04 编译安装指南
1117 0
避坑指南之Samba4在Ubuntu20.04 编译安装指南
|
8月前
|
负载均衡 JavaScript 前端开发
分片上传技术全解析:原理、优势与应用(含简单实现源码)
分片上传通过将大文件分割成多个小的片段或块,然后并行或顺序地上传这些片段,从而提高上传效率和可靠性,特别适用于大文件的上传场景,尤其是在网络环境不佳时,分片上传能有效提高上传体验。 博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
11月前
|
机器学习/深度学习 传感器 人工智能
AI视频监控系统在养老院中的技术实现
AI视频监控系统在养老院的应用,结合了计算机视觉、深度学习和传感器融合技术,实现了对老人体征、摔倒和异常行为的实时监控与分析。系统通过高清摄像头和算法模型,能够准确识别老人的动作和健康状况,并及时向护理人员发出警报,提高护理质量和安全性。
580 14
|
11月前
|
Java Spring
SpringBoot2.7.18拦截器失效不起作用
本文记录了作者在配置Spring Boot项目中的拦截器时遇到的问题。通过复制和修改其他项目的拦截器代码,但发现拦截器始终不生效。最终发现问题出在`WebConfig.java`中配置路径模式的方式上,即在已设置`context-path`的情况下,不应再使用`addPathPatterns(contextPath + &quot;/**&quot;)`。文章提供了详细的配置文件和代码示例,帮助读者理解并避免类似问题。
779 0
|
传感器 数据采集 存储
智能气象站:极端天气的预测与应对
【10月更文挑战第21天】智能气象站集成了高精度传感器、物联网技术和人工智能算法,能够实时监测和预测极端天气,提高预警的准确性和时效性。其在防灾减灾、辅助决策和提升公众意识等方面发挥重要作用,为应对气候变化提供了有力支持。
|
Ubuntu
避坑指南之 Samba4在Ubuntu20.04 编译安装指南
避坑指南之 Samba4在Ubuntu20.04 编译安装指南
947 0
避坑指南之 Samba4在Ubuntu20.04 编译安装指南
|
5G 网络架构 物联网
带你读《5G 系统技术原理与实现》——1.1 5G 网络架构的演进趋势
带你读《5G 系统技术原理与实现》——1.1 5G 网络架构的演进趋势
|
Python
Python中使用os库管理环境变量
在Python中,可以使用os库来管理操作系统的环境变量。通过os.environ对象,我们可以获取、修改和删除环境变量的值。
320 3
|
人工智能 JSON 计算机视觉
AI工具-标注工具labelme
Labelme是一款Python开源图像标注工具,支持图像分类、目标检测、语义分割和实例分割等任务。它提供了一个GUI界面,用户可绘制圆形、方形和多边形进行标注。安装通过`pip install labelme`和`lxml`,使用时可导入预定义标签列表。标注结果保存为json文件,包含类别、边界框信息和形状类型。Labelme还支持格式转换,如转换为VOC或COCO格式。这款工具对视频标注也兼容。5月更文挑战第9天
1252 5
|
Kubernetes Linux 调度
「译文」深入了解 Kubernetes 指标 - 第三部分 - 容器资源指标
「译文」深入了解 Kubernetes 指标 - 第三部分 - 容器资源指标