如何发送 FTP 文件到客户端浏览器?
How to send FTP file to client browser?
我写了asp.net Webservice来生成ftp下载link并发送到客户端浏览器,这样客户端就可以下载了。
link 是这样的:
<a href='ftp://test:test@10:10:10:10:21/test.txt'>download</a>
我通过 Ajax 响应呼叫发送 link。
那么如何防止用户查看我的 ftp 用户名和密码?或者如何加密 link?
方法 #2:
为了避免上述情况 link 我编写了代码来发送大量数据,但浏览器中没有任何反应。
(我正在使用 fluentftp 库。)
[WebMethod(enableSession: true)]
public void GetDownload(string brandName, string modelName, string osName, string file)
{
if (!FtpConnect())
throw new Exception("Error ftp connection.");
byte[] buffer = new byte[1024];
string path = "disk1/Drivers/" + GetFtpBrands(brandName) + "/" + modelName + "/" + osName + "/" +file;
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.ClearContent();
HttpContext.Current.Response.BufferOutput = true;
HttpContext.Current.Response.ContentType = "application/octet-stream";
HttpContext.Current.Response.AddHeader("content-disposition", "attachment;filename=" + file);
FtpDataStream inputStream = (FtpDataStream) ftp.OpenRead(path,FtpDataType.Binary);
int read = 0;
while ((read = inputStream.Read(buffer, 0, buffer.Length)) > 0)
{
HttpContext.Current.Response.OutputStream.Write(buffer, 0, read);
HttpContext.Current.Response.Flush(); // Sends all currently buffered output to the client.
}
inputStream.Close();
HttpContext.Current.Response.OutputStream.Close();
}
和jquery:
function GetDlLink(brandName, model, os, file) {
$.ajax({
type: 'POST',
url: 'WS/Drivers.asmx/GetDownload',
data: JSON.stringify(
{
brandName: brandName,
modelName: model,
osName: os,
file: file
}),
cache: false,
contentType: 'application/json; charset=utf-8',
processData: false,
responseType: 'blob',
// ******* this is important for getting binary response types *******************
xhrFields: {
responseType: 'blob'
},
//==================================================================
// function for openning browser download dialog
success: function(data) {
var blob = new Blob([data]);
var link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
link.download = file;
link.click();
},
error: function(xhr, ajaxOptions, thrownError) {
alert("error");
}
});
}
但是浏览器没有任何反应!!!
您不应使用 ftp://
网址,原因至少有两个:
- 您泄露了凭据(如您所知)并且没有办法隐藏它们;
- 所有主要的网络浏览器都在逐渐 removing a support for FTP。
相反,您必须将下载 link 指向您网站上的脚本。并让脚本从 FTP 下载文件并将其流式传输回网络浏览器。
有关在 ASP.NET 中实施此类脚本的一些示例,请参阅以下问题:
- Download file from FTP and how prompt user to save/open file in ASP.NET C#
我知道将 ftp 站点的用户名和密码发送到客户端浏览器不是安全的方法,因此使用了方法 #2,但在客户端浏览器上没有任何反应。我发现这个技巧可以绕过这一步:
我在 <system.web>
部分
下的 Web.config 文件中启用了 Web 服务协议 Httpget 和 Httppost
<webServices>
<protocols>
<add name="HttpGet"/>
<add name="HttpPost"/>
</protocols>
</webServices>
之后,我删除了 Ajax 调用和 JavaScript "GetDlLink" 函数。
而不是我创建 link 从 Webservice 下载并使用 URL 将参数传递给它,如下所示:
<a href="WS/Drivers.asmx/GetDownload?brandName=brand&modelName=model&osName=os&file=file" >download file</a>
因此不要更改 "GetDownload" 网络方法中的任何代码。
我的客户端单击下载文件和 "GetDownload" 方法连接到 FTP 服务器并检查凭据并取回指定的文件流。在该浏览器获取文件并优雅地打开下载对话框之后。
我写了asp.net Webservice来生成ftp下载link并发送到客户端浏览器,这样客户端就可以下载了。 link 是这样的:
<a href='ftp://test:test@10:10:10:10:21/test.txt'>download</a>
我通过 Ajax 响应呼叫发送 link。
那么如何防止用户查看我的 ftp 用户名和密码?或者如何加密 link?
方法 #2:
为了避免上述情况 link 我编写了代码来发送大量数据,但浏览器中没有任何反应。 (我正在使用 fluentftp 库。)
[WebMethod(enableSession: true)]
public void GetDownload(string brandName, string modelName, string osName, string file)
{
if (!FtpConnect())
throw new Exception("Error ftp connection.");
byte[] buffer = new byte[1024];
string path = "disk1/Drivers/" + GetFtpBrands(brandName) + "/" + modelName + "/" + osName + "/" +file;
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.ClearContent();
HttpContext.Current.Response.BufferOutput = true;
HttpContext.Current.Response.ContentType = "application/octet-stream";
HttpContext.Current.Response.AddHeader("content-disposition", "attachment;filename=" + file);
FtpDataStream inputStream = (FtpDataStream) ftp.OpenRead(path,FtpDataType.Binary);
int read = 0;
while ((read = inputStream.Read(buffer, 0, buffer.Length)) > 0)
{
HttpContext.Current.Response.OutputStream.Write(buffer, 0, read);
HttpContext.Current.Response.Flush(); // Sends all currently buffered output to the client.
}
inputStream.Close();
HttpContext.Current.Response.OutputStream.Close();
}
和jquery:
function GetDlLink(brandName, model, os, file) {
$.ajax({
type: 'POST',
url: 'WS/Drivers.asmx/GetDownload',
data: JSON.stringify(
{
brandName: brandName,
modelName: model,
osName: os,
file: file
}),
cache: false,
contentType: 'application/json; charset=utf-8',
processData: false,
responseType: 'blob',
// ******* this is important for getting binary response types *******************
xhrFields: {
responseType: 'blob'
},
//==================================================================
// function for openning browser download dialog
success: function(data) {
var blob = new Blob([data]);
var link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
link.download = file;
link.click();
},
error: function(xhr, ajaxOptions, thrownError) {
alert("error");
}
});
}
但是浏览器没有任何反应!!!
您不应使用 ftp://
网址,原因至少有两个:
- 您泄露了凭据(如您所知)并且没有办法隐藏它们;
- 所有主要的网络浏览器都在逐渐 removing a support for FTP。
相反,您必须将下载 link 指向您网站上的脚本。并让脚本从 FTP 下载文件并将其流式传输回网络浏览器。
有关在 ASP.NET 中实施此类脚本的一些示例,请参阅以下问题:
- Download file from FTP and how prompt user to save/open file in ASP.NET C#
我知道将 ftp 站点的用户名和密码发送到客户端浏览器不是安全的方法,因此使用了方法 #2,但在客户端浏览器上没有任何反应。我发现这个技巧可以绕过这一步:
我在 <system.web>
部分
<webServices>
<protocols>
<add name="HttpGet"/>
<add name="HttpPost"/>
</protocols>
</webServices>
之后,我删除了 Ajax 调用和 JavaScript "GetDlLink" 函数。 而不是我创建 link 从 Webservice 下载并使用 URL 将参数传递给它,如下所示:
<a href="WS/Drivers.asmx/GetDownload?brandName=brand&modelName=model&osName=os&file=file" >download file</a>
因此不要更改 "GetDownload" 网络方法中的任何代码。
我的客户端单击下载文件和 "GetDownload" 方法连接到 FTP 服务器并检查凭据并取回指定的文件流。在该浏览器获取文件并优雅地打开下载对话框之后。