簡體   English   中英

隱藏ASP.NET中文件下載的物理路徑

[英]Hiding the physical path of a file downloading in ASP.NET

我想讓某些用戶從我的網站下載一些文件,但我不希望他們看到下載文件的物理路徑。

我將文件移動到Web文件夾之外的文件夾中,並使用Response.WriteFile(filePath)下載它們。 這可以幫助我隱藏路徑,但是此方法不支持我真正想要的簡歷下載。

那么,您推薦我使用哪種方法?

創建一個臨時目錄並將文件復制到該目錄中。 您甚至可以將文件重命名為其他名稱,以使其“不可猜測”。

我假設他們是否可以下載文件,該文件的內容適用於該人,因此用戶知道直接鏈接不會有問題。 其他人將無法猜測隨機目錄和/或文件名。

var directoryName = String.Format("{0}\{1}\{2}", 
Server.MapPath("original Path"),System.Guid.NewGuid().Replace("-",""), fileName);

這與我們從系統中導出信息的過程幾乎相同。

很簡單,我之前已經做過。 只需隱藏“輸入文件”控件,即可將其隱藏在UI上,然后創建一個按鈕,該按鈕的click事件會觸發“ input file”控件的click事件。 然后,您還可以使用javascript(在我的情況下為JQuery)將瀏覽文件的名稱帶入代表文件名稱的文本框中。

因此,文件路徑對UI隱藏。

我將實現一個文件處理程序(.ashx文件),該文件處理程序根據查詢字符串中的某種ID或名稱為文件提供服務,並像這樣發送:

asp.net ashx處理程序提示下載而不是顯示文件

這是最好的方法:

    public static bool DownloadFile(HttpContext httpContext, string filePath, long speed)
    {
        // Many changes: mostly declare variables near use
        // Extracted duplicate references to HttpContext.Response and .Request
        // also duplicate reference to .HttpMethod

        // Removed try/catch blocks which hid any problems
        var response = httpContext.Response;
        var request = httpContext.Request;
        var method = request.HttpMethod.ToUpper();
        if (method != "GET" &&
            method != "HEAD")
        {
            response.StatusCode = 501;
            return false;
        }

        if (!File.Exists(filePath))
        {
            response.StatusCode = 404;
            return false;
        }

        // Stream implements IDisposable so should be in a using block
        using (var myFile = new FileStream(filePath, FileMode.Open, FileAccess.Read))
        {
            var fileLength = myFile.Length;
            if (fileLength > Int32.MaxValue)
            {
                response.StatusCode = 413;
                return false;
            }

            var lastUpdateTiemStr = File.GetLastWriteTimeUtc(filePath).ToString("r");
            var fileName = Path.GetFileName(filePath);
            var fileNameUrlEncoded = HttpUtility.UrlEncode(fileName, Encoding.UTF8);
            var eTag = fileNameUrlEncoded + lastUpdateTiemStr;

            var ifRange = request.Headers["If-Range"];
            if (ifRange != null && ifRange.Replace("\"", "") != eTag)
            {
                response.StatusCode = 412;
                return false;
            }

            long startBytes = 0;

            // Just guessing, but I bet you want startBytes calculated before
            // using to calculate content-length
            var rangeHeader = request.Headers["Range"];
            if (rangeHeader != null)
            {
                response.StatusCode = 206;
                var range = rangeHeader.Split(new[] { '=', '-' });
                startBytes = Convert.ToInt64(range[1]);
                if (startBytes < 0 || startBytes >= fileLength)
                {
                    // TODO: Find correct status code
                    response.StatusCode = (int)HttpStatusCode.BadRequest;
                    response.StatusDescription =
                        string.Format("Invalid start of range: {0}", startBytes);
                    return false;
                }
            }

            response.Clear();
            response.Buffer = false;
            response.AddHeader("Content-MD5", GetMD5Hash(filePath));
            response.AddHeader("Accept-Ranges", "bytes");
            response.AppendHeader("ETag", string.Format("\"{0}\"", eTag));
            response.AppendHeader("Last-Modified", lastUpdateTiemStr);
            response.ContentType = "application/octet-stream";
            response.AddHeader("Content-Disposition", "attachment;filename=" +
                                                        fileNameUrlEncoded.Replace("+", "%20").Replace(",",";"));
            var remaining = fileLength - startBytes;
            response.AddHeader("Content-Length", remaining.ToString());
            response.AddHeader("Connection", "Keep-Alive");
            response.ContentEncoding = Encoding.UTF8;

            if (startBytes > 0)
            {
                response.AddHeader("Content-Range",
                                    string.Format(" bytes {0}-{1}/{2}", startBytes, fileLength - 1, fileLength));
            }

            // BinaryReader implements IDisposable so should be in a using block
            using (var br = new BinaryReader(myFile))
            {
                br.BaseStream.Seek(startBytes, SeekOrigin.Begin);

                const int packSize = 1024 * 10; //read in block,every block 10K bytes
                var maxCount = (int)Math.Ceiling((remaining + 0.0) / packSize); //download in block
                for (var i = 0; i < maxCount && response.IsClientConnected; i++)
                {
                    response.BinaryWrite(br.ReadBytes(packSize));
                    response.Flush();

                    // HACK: Unexplained sleep
                    var sleep = (int)Math.Ceiling(1000.0 * packSize / speed); //the number of millisecond
                    if (sleep > 1) 
                        Thread.Sleep(sleep);
                }
            }
        }
        return true;
    }

    static string GetMD5Hash(string input)
    {
        // Create a new instance of the MD5CryptoServiceProvider object.
        MD5 md5Hasher = MD5.Create();

        // Convert the input string to a byte array and compute the hash.
        byte[] data = md5Hasher.ComputeHash(Encoding.Default.GetBytes(input));

        // Create a new Stringbuilder to collect the bytes
        // and create a string.
        StringBuilder sBuilder = new StringBuilder();

        // Loop through each byte of the hashed data 
        // and format each one as a hexadecimal string.
        for (int i = 0; i < data.Length; i++)
        {
            sBuilder.Append(data[i].ToString("x2"));
        }

        // Return the hexadecimal string.
        return sBuilder.ToString();
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM