简体   繁体   English

在 html 锚链接上下载音频文件,单击独立于浏览器操作

[英]Download audio file on html anchor link click independant of browser action

I am having an anchor link on the page which points to an MP3 file.我在页面上有一个指向 MP3 文件的锚链接。 I want to be able to download this file with Right-click + Save Target As.. and also by single clicking on the link .我希望能够通过Right-click + Save Target As..以及单击链接来下载此文件。

Currently, I am facing a problem where different browsers have different behavior.目前,我面临着不同浏览器有不同行为的问题。 IE plays the file in WMP, Firefox prompts the download box and Chrome starts playing file inline. IE 在 WMP 中播放文件,Firefox 提示下载框,Chrome 开始内联播放文件。 Expected behavior on single click is that browser should either download the file or give me a download dialog.单击时的预期行为是浏览器应该下载文件或给我一个下载对话框。

I have tried following:我试过以下:

  • Creating a hidden iframe on the page and giving it is as target for my anchor link, also tried creating a form with my desired MP3 file location as its action inside this iframe and submitting the form on anchor link click event在页面上创建一个隐藏的iframe并将其作为我的锚链接的目标,还尝试使用我想要的 MP3 文件位置创建一个表单作为它在此iframe并在锚链接单击事件上提交表单
  • Setting window.location = MP3 URL on link click在链接点击时设置window.location = MP3 URL
  • Tried multiple combinations of window.open尝试了window.open多种组合

None of these has been able to help me.这些都无法帮助我。 I just can't get the download dialog on link-click.我只是无法通过单击链接获得下载对话框。

The innocent anchor link looks like:无辜的锚链接看起来像:

<a id="someID" href="myMP3file" target="whatever" title="Download" class="someClass">Download Me!</a>

Just to post the beginnings of a proper answer.只是为了发布正确答案的开头。 I think I would use a http handler (.ashx) file to code up some custom handling for these files - this tutorial shows an example.我想我会使用一个 http 处理程序 (.ashx) 文件来为这些文件编写一些自定义处理 - 本教程展示了一个示例。

Your link would be something like您的链接将类似于

<a href="MyMp3Handler.ashx?fileName=MyFile">Click here to download</a>

The handler would do the streaming work.处理程序将执行流式处理工作。

Example of what the handler might look like (based on this SO question )处理程序可能是什么样子的示例(基于这个SO question

public void ProcessRequest (HttpContext context) {

    var filePath = Server.MapPath(context.Request.QueryString["fileName"].ToString()) + ".mp3";          
    if (!File.Exists(filePath))             
        return;          

    var fileInfo = new System.IO.FileInfo(filePath);         
    Response.ContentType = "application/octet-stream";         
    Response.AddHeader("Content-Disposition", String.Format("attachment;filename=\"{0}\"", filePath));         
    Response.AddHeader("Content-Length", fileInfo.Length.ToString());         
    Response.WriteFile(filePath);         
    Response.End();
}

The handler also needs to be registered in the web.config.处理程序还需要在 web.config 中注册。

Note though - this is off the top of my head so code will need tweaking to work.请注意 - 这超出了我的脑海,因此代码需要调整才能工作。 Just thought I'd pop in how i would start off只是想我会突然出现我将如何开始

Additional Note附加说明

A colleague has just pointed out that even with content type set to application/octet-stream it is still up to the browser implementation of how that gets rendered so it still may not stream.一位同事刚刚指出,即使内容类型设置为application/octet-stream它仍然取决于浏览器实现如何呈现,因此它仍然可能无法流式传输。 That said I did something similar but in PHP and I got the mp3 file streaming down in Firefox, IE and Chrome so the principle does work.也就是说,我做了类似的事情,但在 PHP 中,我在 Firefox、IE 和 Chrome 中下载了 mp3 文件,因此该原理确实有效。 I provided the example in asp.net since that is what your question was tagged as.我在 asp.net 中提供了示例,因为这就是您的问题被标记为的内容。

@CrabBucket - Here's how I solved my issue!! @CrabBucket - 这是我解决问题的方法!! Works great for me :) I was using a controller action to initiate this download from this server side (this is why I did not use a handler).对我来说很好用 :) 我使用控制器动作从这个服务器端启动这个下载(这就是我没有使用处理程序的原因)。 Returning an http response from the controller seemed tricky initially but then I figured out a way to cheat the thing ;) I had to write the following code inside my controller action -从控制器返回一个 http 响应最初似乎很棘手,但后来我想出了一种作弊的方法;) 我不得不在我的控制器操作中编写以下代码 -

{
    HttpWebRequest myRequest = (HttpWebRequest)HttpWebRequest.Create(FileURL);
    HttpWebResponse myResponse = (HttpWebResponse)myRequest.GetResponse();

    Stream myStream = myResponse.GetResponseStream();

    Response.ContentType = "application/octet-stream";
    Response.AddHeader("Content-Disposition", "attachment; filename=\"SaveMe.MP3\"");

    var readBytes = 10000000;
    var myAudResponse = new byte[readBytes];
    int fileLength;
    do {
        fileLength = myStream.Read(myAudResponse, 0, (int)readBytes);
        Response.OutputStream.Write(myAudResponse, 0, fileLength);
        Response.Flush();
    } while (fileLength > 0);
    myStream.Close();

    return new EmptyResult();
}

Use the basic Try-Catch, etc as per your wisdom :) A lot of thanks to various web-forums and also to CrabBucket (the SO question from where you posted the code, had an answer which was very much help!) goes without saying!根据您的智慧使用基本的 Try-Catch 等 :) 非常感谢各种网络论坛以及 CrabBucket(您发布代码的地方的 SO 问题,有一个非常有帮助的答案!)没有说!


Sorry for multiple edits!抱歉多次修改! My code failed for a moment.我的代码失败了一会儿。 I guess, loops are always the way to go!!!我想,循环总是要走的路!!!

You can simply use the anchor tag's "download" attribute.您可以简单地使用锚标记的“下载”属性。

<a href='your_link' download='file_name'>Download_ME!</a>

This worked for me and personally, I prefer to stick with whatever default customizations are provided.这对我和我个人都有效,我更喜欢坚持使用提供的任何默认自定义设置。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM