转载:利用html5分片上传超大文件
转载:PHP文件上传问题
转载:前端上传组件Pupload的使用
前端:
推荐采用 pupload插件;下面是原生写法:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<title>HTML5大文件分片上传示例</title>
<script src="../Scripts/jquery-1.11.1.min.js"></script>
<script>
var page = {
init: function(){
$("#upload").click($.proxy(this.upload, this));
},
upload: function(){
var file = $("#file")[0].files[0], //文件对象
name = file.name, //文件名
size = file.size, //总大小
succeed = 0;
var shardSize = 2 * 1024 * 1024, //以2MB为一个分片
shardCount = Math.ceil(size / shardSize); //总片数
for(var i = 0;i < shardCount;++i){
//计算每一片的起始与结束位置
var start = i * shardSize,
end = Math.min(size, start + shardSize);
//构造一个表单,FormData是HTML5新增的
var form = new FormData();
form.append("data", file.slice(start,end)); //slice方法用于切出文件的一部分
form.append("name", name);
form.append("total", shardCount); //总片数
form.append("index", i + 1); //当前是第几片
//Ajax提交
$.ajax({
url: "../File/Upload",
type: "POST",
data: form,
async: true, //异步
processData: false, //很重要,告诉jquery不要对form进行处理
contentType: false, //很重要,指定为false才能形成正确的Content-Type
success: function(){
++succeed;
$("#output").text(succeed + " / " + shardCount);
}
});
}
}
};
$(function(){
page.init();
});
</script>
</head>
<body>
<input type="file" id="file" />
<button id="upload">上传</button>
<span id="output" style="font-size:12px">等待</span>
</body>
</html>
服务器端:
作者:金正
链接:https://www.zhihu.com/question/19602751/answer/140504402
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
1、文件分片如果对于上传的文件是有所预期并且有所限制的,比如图片,小文档,确实可以考虑不做文件分片。但是当你的文件动辄几百兆,一个G,不管是出于容错还是服务器配置的合理性来说,文件分片都是必须的。很不幸当时我的上传内容是游戏安装包,动不动1个G啊。实现原理很简单,前端把文件切片后,每一片的提交都带上几个参数(共几片、本次是第几片、会话id),服务端当检查到所有分片都到齐后合并文件。(分片上传可以分为同步上传和异步上传,同步上传不会出现同时上传多个分片,因此只需要传来一个分片文件就合并一个分片文件,全程都只是合并在一个分片文件中。异步上传会同时上传多个文件,因此是在传输完成后将所有的文件进行合并处理。两者在服务器中处理的方式不同)此处出现CASE: 合并后文件错误。原因:网络原因等会出现数据传输不可靠。解决办法: 检查文件MD5,但是这需要在合并后才能检查的,更进阶的是每一个分片的md5都要检查,错误的分片立刻要求重传。不过这要注意前端效率问题,js下md5库还是比较慢的,每一片都检查的话会花费较多时间。
2、服务器配置建议为文件上传的url location单独配置服务器,因为这些参数在常规访问中是很离谱的。以nginx+php为例子:php要修改post_max_size和upload_max_filesizenginx要修改client_max_body_size, client_body_buffer_size,fastcgi_send_timeout 等等如果是跨域上传,nginx上对option请求的支持也是必须的,详情可以了解下CORS原理。
3、由于content-type:false,所以默认上传文件的头部信息为:content-type:form/data;因此,在php缓冲流中无法获取数据,只能是有$_POST
和$_FILE
获取数据。
服务器代码:
$files = $_FILES['data'];
$data = $_POST;
$content = file_get_contents($files['tmp_name']);
file_put_contents(storage_path('file/').$_POST['name'],$content,FILE_APPEND);//同一个文件名称追加