重拾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写到磁盘上。

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

目录
相关文章
|
3月前
|
关系型数据库 MySQL PHP
php网上书城|基于PHP实现网上书店商城藉项目(一)
php网上书城|基于PHP实现网上书店商城藉项目
|
3月前
|
安全 数据库连接 PHP
php网上书城|基于PHP实现网上书店商城藉项目(二)
php网上书城|基于PHP实现网上书店商城藉项目
|
4月前
|
安全 关系型数据库 PHP
php网上书城|基于PHP实现网上书店商城藉项目
php网上书城|基于PHP实现网上书店商城藉项目
|
10月前
|
弹性计算 安全
dedecms上传漏洞uploadsafe.inc.php 整理
自从买了阿里云的ecs 之后每次出现漏洞阿里云盾就会通知,前段时间部署的项目检测出上传漏洞 根据网上大神们的博客整理了下,下面这个是可行的 dedecms上传漏洞uploadsafe.inc.php,这里整理了大神们对于这个漏洞的解释
76 0
|
11月前
|
开发框架 安全 前端开发
|
JavaScript Java 数据安全/隐私保护
浅谈JSP Webshell进阶免杀(一)
浅谈JSP Webshell进阶免杀
743 0
|
算法 JavaScript Java
浅谈JSP Webshell进阶免杀(二)
浅谈JSP Webshell进阶免杀
234 0
|
安全 Java
浅谈JSP Webshell进阶免杀(三)
浅谈JSP Webshell进阶免杀
583 0
|
JSON 安全 PHP
【代码审计-PHP】基于Thinkphp框架开发的
【代码审计-PHP】基于Thinkphp框架开发的
141 0
【代码审计-PHP】基于Thinkphp框架开发的
|
SQL 前端开发 JavaScript
开心档-软件开发入门之PHP - AJAX 与 MySQL
本文主要讲解AJAX 可用来与数据库进行交互式通信。