前言

踩过的坑


1、WebAPI跨域

2、Jquery ajax低版本不支持XHR 2功能

3、Jquery ajax不支持Deferred的process事件

4、IE下文件名乱码问题

功能实现

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title></title>
<meta charset="utf-8" />
<script src="https://code.jquery.com/jquery-3.2.1.min.js "></script>
</head>
<body>
<input type="button" value="全部下载" onclick="doAllDownload()" />
<div>
<ul>
<li>
<span>文件1.txt</span>&nbsp;&nbsp;<span id="progress1"></span>
</li>
<li>
<span>文件2.txt</span>&nbsp;&nbsp;<span id="progress2"></span>
</li>
<li>
<span>文件3.txt</span>&nbsp;&nbsp;<span id="progress3"></span>
</li>
</ul>
</div>
<script>
function doAllDownload() {
/**
测试:
1、文件3数据量大
2、文件2不存在
**/
var files = [];
files.push({ url: 'D:\\Test\\1.txt', id: 'progress1' });
files.push({ url: 'D:\\Test\\2.txt', id: 'progress2' });
files.push({ url: 'D:\\Test\\3.txt', id: 'progress3' });
files.forEach(function (item) {
//多文件下载
DownloadFile(item.url).then(function (result) {
//请求完成
var msg = "文件下载完毕!";
if (result.error) {
msg = result.error.message ? result.error.message : "文件下载错误!";
}
$("#" + item.id).html(msg);
}, function (err) { }, function (evt) {
//根据item处理进度条数据
$("#" + item.id).html("已下载 " + parseInt(100 * evt.loaded / evt.total) + "%");
});
})
}
function DownloadFile(url) {
var filename = url.substr(url.lastIndexOf('\\') + 1);//文件名
var dfd = new $.Deferred();
var promise = $.ajax("http://localhost:2032/api/Test/DownloadFileUrl", {
type: "POST",
contentType: 'application/json',
data: JSON.stringify({ url: url }),
/*JQuery 3.0以下版本不支持*/
xhrFields: {
responseType: 'arraybuffer',
onprogress: dfd.notify//触发dfd.process事件
}
});
promise.then(function (data, status, xhr) {
if (xhr.statusText == "OK") {
var type = xhr.getResponseHeader('Content-Type');
var blob = new Blob([data], { type: type });
if (typeof window.navigator.msSaveBlob !== 'undefined') {
window.navigator.msSaveBlob(blob, filename);
} else {
var URL = window.URL || window.webkitURL;
var downloadUrl = URL.createObjectURL(blob);
if (filename) {
var a = document.createElement("a");
if (typeof a.download === 'undefined') {
window.location = downloadUrl;
} else {
a.href = downloadUrl;
a.download = filename;
document.body.appendChild(a);
a.click();
}
} else {
window.location = downloadUrl;
} setTimeout(function () {
URL.revokeObjectURL(downloadUrl);
dfd.resolve({});
}, 100);
}
} else {
dfd.resolve({ error: { message: xhr.statusText } });
}
}, function (err) {
//异常处理
}, function (info) {
//不支持Deferred的process事件
});
return dfd;
}
</script>
</body>
</html>

Asp.NET后台代码

1、为了设置进度条 故设置 BUFFER_SIZE 为 5 开发时请注意,跨域设置请自行在Web.config或者WebApiConfig.cs里面设置。就不上代码了,网上很多例子!
2、文件名乱码问题:请参考 https://my.oschina.net/pingpangkuangmo/blog/376332
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Http; namespace WebAPI.Controllers
{
public class TestController:ApiController
{
private const int BUFFER_SIZE = ;
[HttpPost]
public void DownloadFileUrl(dynamic args)
{
string url = args.url;
string filename = url.Substring(url.LastIndexOf('\\') + );
var response = HttpContext.Current.Response;
if (File.Exists(url))
{
byte[] buffer = new byte[BUFFER_SIZE];
response.Clear();
//跨域处理
response.AddHeader("Access-Control-Allow-Origin", "*");//支持所有跨域请求
response.AddHeader("Access-Control-Allow-Headers", "*");//支持所有Access-Control-Request-Headers字段 response.ContentType = "application/octet-stream";//定义stream为下载类型的窗口
response.AddHeader("Content-Disposition", "attachment;filename=" + filename);
using (var stream = File.Open(url, FileMode.Open, FileAccess.Read, FileShare.Read))
{
//CORS请求时可访问 Content-Length
var sHeaders = response.Headers["Access-Control-Expose-Headers"] + ",Content-Length";
response.Headers.Remove("Access-Control-Expose-Headers");
response.AddHeader("Access-Control-Expose-Headers", sHeaders); long total = stream.Length;//文件总大小
response.AddHeader("Content-Length", total.ToString());
response.Charset = "UTF-8";
while (total > && response.IsClientConnected)
{
int read = stream.Read(buffer, , BUFFER_SIZE);//读取的大小
response.OutputStream.Write(buffer, , read);
response.Flush();
total = total - read;
}
response.End();
}
}
else
{
response.Clear();
response.AddHeader("Access-Control-Allow-Origin", "*");//支持所有跨域请求
response.AddHeader("Access-Control-Allow-Headers", "*");//支持所有Access-Control-Request-Headers字段
response.StatusCode = ;
response.Status = "200 File_Not_Found";
response.Write("{\"Message\":\"File Not Found\",\"Status\":\"ERROR\"}");
response.End();
}
} }
}
测试结果:
文件准备 D:\\Test\1.txt(数据过多) D:\\Test\3.txt(数据略少) 两个文件,文件 2.txt 不存在。

H5+Ajax+WebApi实现文件下载(进度条,多文件)的更多相关文章

  1. Ajax实现带进度条的文件上传

    Ajax实现带进度条的文件上传 文件上传页面运行效果 上传文件并显示进度条运行效果 代码如下; DiskFileItemFactory factory = new DiskFileItemFactor ...

  2. jQuery ajax 标准写法及进度条绘制

    jQuery ajax 标准写法及进度条绘制 $.ajax({ url: "http://www.microsoft.com", //请求的url地址 dataType: &quo ...

  3. Python展示文件下载进度条

    前言 大家在用Python写一些小程序的时候,经常都会用到文件下载,对于一些较小的文件,大家可能不太在乎文件的下载进度,因为一会就下载完毕了. 但是当文件较大,比如下载chromedriver的时候, ...

  4. cordova加载层、进度条、文件选择插件

    在做cordova项目的时候,感觉应用的响应速度跟原生应用比相差甚远,一个主要问题就是如加载层.进度条等弹出对话框的效率不行.毕竟项目中的这些弹框都是用dom拼成的,dom的渲染效率和原生控件比起来慢 ...

  5. ajax页面加载进度条插件

    下面两个都是youtube视频的加载进度条效果的ajax插件 一.官网:http://ricostacruz.com/nprogress/官网 github:https://github.com/rs ...

  6. 给H5页面添加百分比的进度条,精确度高

    进度条样式地址:http://sandbox.runjs.cn/show/6vxbxjrf SVG圆环样式地址:http://sandbox.runjs.cn/show/3ho1qpe9 原理:由于H ...

  7. asp.net利用ajax和jquery-ui实现进度条

    前台用ajax不停进行查询,直到任务完成.进度条用的是jquery-ui.后台用一般处理程序处理相应,进度信息保存在HttpContext.Application中. 代码作为简单示例,实际应用时应对 ...

  8. Ajax技术——带进度条的文件上传

    1.概述 在实际的Web应该开发或网站开发过程中,经常需要实现文件上传的功能.在文件上传过程中,经常需要用户进行长时间的等待,为了让用户及时了解上传进度,可以在上传文件的同时,显示文件的上传进度条.运 ...

  9. H5 可堆叠的圆环进度条,支持任意数量子进度条

    by Conmajia SN: S22-W1M 由来 看到一篇帖子<vue实用组件--圆环百分比进度条>,让我想起了很多年前我在WinForm下仿制过的Chrome进度条. ▲ 原版进度条 ...

随机推荐

  1. String类为什么要用final修饰(面试回答)

    String是所有语言中最常用的一个类.我们知道在Java中,String是不可变的.final的.Java在运行时也保存了一个字符串池(String pool),这使得String成为了一个特别的类 ...

  2. 如何解决更新被拒绝,因为远程版本库包含您本地尚不存在的提交。这通常是因为另外 提示:一个版本库已向该引用进行了推送。再次推送前,您可能需要先整合远程变更 提示:(如 'git pull ...')。

    不要通过网页提交,通过网页提交一次,然后在终端再次push的时候,会认为网上代码仓库已经被其他地方提交过一次代码,此时会拒绝终端push 这个时候只能是pull,然后才能再次在终端提交. 也就是说,避 ...

  3. CrawlSpiders

    1.用 scrapy 新建一个 tencent 项目 2.在 items.py 中确定要爬去的内容 # -*- coding: utf-8 -*- # Define here the models f ...

  4. 【java】实例化对象的3种方式:new、clone、反射

    实例化对象的3种方式:new.clone.反射

  5. std::shared_ptr<void>的工作原理

    前戏 先抛出两个问题 如果delete一个指针,但是它真实的类型和指针类型不一样会发生什么? 是谁调用了析构函数? 下面这段代码会发生什么有趣的事情? // delete_diff_type.cpp ...

  6. IOS学习3——代理

    本文转载自:你真的了解iOS代理设计模式吗? 在项目中我们经常会用到代理的设计模式,这是iOS中一种消息传递的方式,也可以通过这种方式来传递一些参数.这篇文章会涵盖代理的使用技巧和原理,以及代理的内存 ...

  7. (转)iOS-Runtime知识点整理

    runtime简介 因为Objc是一门动态语言,所以它总是想办法把一些决定工作从编译连接推迟到运行时.也就是说只有编译器是不够的,还需要一个运行时系统 (runtime system) 来执行编译后的 ...

  8. scala写算法-用小根堆解决topK

    topK问题是指从大量数据中获取最大(或最小)的k个数,比如从全校学生中寻找成绩最高的500名学生等等. 本问题可采用小根堆解决.思路是先把源数据中的前k个数放入堆中,然后构建堆,使其保持堆序(可以简 ...

  9. async和enterproxy控制并发数量

    聊聊并发与并行 并发我们经常提及之,不管是web server,app并发无处不在,操作系统中,指一个时间段中几个程序处于已经启动运行到完毕之间,且这几个程序都是在同一处理机上运行,并且任一个时间点只 ...

  10. HBase0.98使用ReplicationAdmin管理集群同步

    公司datalink平台负责从各种数据源读取数据并同步到其他的同步或者异构数据源,最近增加的HBase的reader利用到了Hbase的Replication特性. 正常情况下,我们配置HBase的R ...