Ajax请求过程中下载文件在FireFox(火狐)浏览器下的
需求很简单,点击一个文件链接下载该文件,向后台发送请求。需求很常见,用户点击下载后通常要进行下载量的统计,统计的话可以利用 script标签 或者 img标签(图片ping) 的跨域能力,将它们的 src 属性指向统计地址,这次用了 ajax 进行统计,遂出现了这个问题。
demo 代码如下
<a id="a" href="http://c758482.r82.cf2.rackcdn./Sublime Text 2.0.2 x64 Setup.exe" >click</a> <script src="jQuery.js"></script> <script> document.getElementById("a").onclick = function(e) { $.post("data.php"); }; </script>
我们都知道,如果一个 a 标签拥有 onclick 事件和 href 属性,onclick 事件的回调会在默认事件(即跳转)之前执行,这也正是可以在 onclick 事件中用类似 e.preventDefault() 的代码去除默认事件(即跳转)的原因。所以以上代码,如果点击 a 标签,会执行 onclick 事件的回调,即发送 ajax 请求,理论上,因为代码中的 ajax 是异步的(其实同步也一样),所以会一边请求一边打开下载文件。
chrome、UC、opera、2345浏览器中表现均和预期一致,firefox 下点击能跳出下载文件, ajax 部分报错,IE 下未测试。
一开始的错误想法是,跨域导致报错。当点击下载链接时,ajax 请求会以为页面即将跳到 href 所指的地址,导致浏览器以为该 ajax 跨域。该错误想法很快被推翻,一是因为先进行 ajax 请求,所以请求瞬间并未跨域;二是并未报跨域错误(通常如果是跨域错误控制台会指出);三是如下代码更进一步证明了该错误。
<a id="a" href="http://c758482.r82.cf2.rackcdn./Sublime Text 2.0.2 x64 Setup.exe" >click</a> <script src="jQuery.js"></script> <script> $.post("data.php"); // data.php sleep(100) </script>
打开该页面,随即进行 ajax 请求,一旦点击了下载按钮,请求即被中止。如果 a 标签的 href 属性值不是文件地址,而是用任意的一个 url 替换,如果点击 a 标签,页面会立即跳转到该标签所指向的地址,页面都不存在了,ajax 自然也就中断了。如果 a 标签指向的是文件地址,在 ff 下是不是也会被一样地解析呢(浏览器以为要跳到该地址了,而将 ajax 中止)?
答案是肯定的,我在 stackoverflow 中找到了答案。
When clicking the download link you are leaving the page, even it does not look so. If there would no file transfer, you would see the requested page.. try to set a target="_blank" or use an iframe as target for the link.
从提问可以看出,2010 年时 chrome 和 ff 都有类似的问题,而 chrome 或者说是 webkit 内核的浏览器在之后的版本迭代中修复了这个问题, ff 则一直将问题留到了现在(个人认为这不太合理)。
知道了问题的根源,解决方案也就呼之欲出了。
方法一
最简单的方法无非是给 a 标签加上 target="_blank",事实上,通常网页都是这么做的,这也是值得肯定的做法。
方法二
既然 a 标签的默认行为会使得 ajax 请求中断,那么将 "默认行为" 放在请求之前呢?
<a id="a" href="javascript:;" >click</a> <script src="jQuery.js"></script> <script> document.getElementById("a").onclick = function(e) { location.href = "http://c758482.r82.cf2.rackcdn./Sublime Text 2.0.2 x64 Setup.exe"; $.post("data.php"); }; </script>
方法三
设置定时器使请求延迟,因为 a 标签的默认跳转不属于 Javascript 线程能控制的范围,所以这个延迟阈值的设置非常重要,我本地测试结果居然是 2ms(也是万万没想到),一般设置为 100ms 左右就 ok 了。 这个方法不优雅,不应该使用 。
<a id="a" href="http://c758482.r82.cf2.rackcdn./Sublime Text 2.0.2 x64 Setup.exe" >click</a> <script src="jQuery.js"></script> <script> document.getElementById("a").onclick = function(e) { setTimeout(function() { $.post("data.php"); }, 100); }; </script>
以上内容给大家介绍了Ajax请求过程中下载文件在FireFox(火狐)浏览器下的兼容问题,希望对大家今后的工作学习有所帮助。
编程语言
- 如何快速学会编程 如何快速学会ug编程
- 免费学编程的app 推荐12个免费学编程的好网站
- 电脑怎么编程:电脑怎么编程网咯游戏菜单图标
- 如何写代码新手教学 如何写代码新手教学手机
- 基础编程入门教程视频 基础编程入门教程视频华
- 编程演示:编程演示浦丰投针过程
- 乐高编程加盟 乐高积木编程加盟
- 跟我学plc编程 plc编程自学入门视频教程
- ug编程成航林总 ug编程实战视频
- 孩子学编程的好处和坏处
- 初学者学编程该从哪里开始 新手学编程从哪里入
- 慢走丝编程 慢走丝编程难学吗
- 国内十强少儿编程机构 中国少儿编程机构十强有
- 成人计算机速成培训班 成人计算机速成培训班办
- 孩子学编程网上课程哪家好 儿童学编程比较好的
- 代码编程教学入门软件 代码编程教程