Javascript לביצוע עיבוד לאחר הורדת קובץ

עודכן דף :
תאריך יצירת דף :

סביבת אימות פעולה

Visual Studio
  • Visual Studio 2022
ASP.NET Core
  • 8.0 (דפי Razpr, MVC)
דפדפני אינטרנט
  • קצה 119

סביבת הפעלה

Visual Studio (אם אתה כולל גם תוכניות שרת)
  • Visual Studio 2022
ASP.NET Core (אם הוא כולל גם תוכניות שרת)
  • 8.0 (דפי Razpr, MVC)
דפדפני אינטרנט
  • גבול
  • גוגל כרום
  • דפדפנים אחרים (לא כולם מסומנים)

(* הגוף העיקרי של טיפ זה הוא תהליך בצד הלקוח, כך שצד השרת יכול להיות כל דבר)

בהתחלה

המוקד העיקרי של טיפים אלה הוא תוכנית הלקוח (Javascript), ואת תוכנית השרת הוא שם רק כדי להוריד קבצים. לכן, זה לא משנה מה תוכנית השרת, כל עוד זה יכול לגרום לך להוריד את הקובץ.

בקש ממשתמשים להוריד קבצים כאשר מתבצעת גישה אליהם בשרת

Mr./Ms. מאפשר לך להוריד קבצים כאשר אתה מקבל בקשה. באותו זמן, אנחנו בכוונה לחכות כמות מסוימת של זמן בשרת, כך שקל להבין את ההתחלה והסוף של ההורדה.

הנה מה שקורה בצד השרת של Razor Pages ו-MVC: באפשרותך ליישם אותו בפרוייקטים אחרים, כגון Web API.

דפי גילוח : עמודים/Index.cshtml.cs

// 省略

namespace DownloadCompleteNotifyRazorPages.Pages
{
  public class IndexModel : PageModel
  {
    // 省略

    /// <summary>時間をかけてファイルをダウンロードします。</summary>
    public async Task<IActionResult> OnGetDownload()
    {
      // ダウンロード開始と完了を明確にする目的で待機を入れる
      await Task.Delay(5000);

      // 適当にファイルを作って返す
      var fileSize = 10_000_000;
      var sb = new System.Text.StringBuilder(fileSize);
      for (int i = 0; i < fileSize; i++) sb.Append('a');
      using var stream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(sb.ToString()));
      return File(stream.ToArray(), "text/plain", $"ダウンロード.txt");
    }
  }
}

MVC : Coletollers/HomeController.cs

// 省略

namespace DownloadCompleteNotifyMvc.Controllers
{
  public class HomeController : Controller
  {
    // 省略

    /// <summary>時間をかけてファイルをダウンロードします。</summary>
    public async Task<IActionResult> Download()
    {
      // ダウンロード開始と完了を明確にする目的で待機を入れる
      await Task.Delay(5000);

      // 適当にファイルを作って返す
      var fileSize = 10_000_000;
      var sb = new System.Text.StringBuilder(fileSize);
      for (int i = 0; i < fileSize; i++) sb.Append('a');
      using var stream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(sb.ToString()));
      return File(stream.ToArray(), "text/plain", $"ダウンロード.txt");
    }
  }
}

עיבוד לקוחות

בדרך כלל, אתה מוריד קובץ על-ידי גישה לכתובת URL שצוינה בדפדפן אינטרנט. אם אתה רוצה לעשות משהו לאחר השלמת ההורדה, אתה יכול להפעיל את ההורדה עם Javascript.

ישנן דרכים רבות לעשות זאת, אבל במקרה זה, נשתמש , שהוא גם XMLHttpRequest המקור של עיבוד אסינכרוני. באפשרותך גם להשתמש בפונקציות ajax של jQuery או ב- API של Fetch.

ahref כתובת ה-URL להורדה נכתבת בתג והתהליך id מבוצע כאשר לוחצים על כתובת ה-URL שהוגדרהdownload.

$('#download').click(function (e) {
  console.log('ダウンロードを開始します。');
  e.preventDefault();  // href による画面遷移を抑止
  let url = $(e.target).attr('href');  // href からダウンロード URL 取得

  const xhr = new XMLHttpRequest();
  xhr.open('GET', url, true);   // ダウンロード先 URL 設定
  xhr.responseType = 'blob';   // バイナリデータ取得であることを指示

  // ダウンロード完了後の処理を設定。この時点ではデータは取得してクライアントにありますが保存はしていません。
  xhr.onload = function (oEvent) {
    if (xhr.status !== 200) {
      console.log(`データの取得に失敗しました。(status=${xhr.status})`);
    } else {
      // 取得したデータ
      let blob = xhr.response;

      // レスポンスヘッダーからサーバーから送られてきたファイル名を取得する
      let fileName = '';
      let disposition = xhr.getResponseHeader('Content-Disposition');
      if (disposition && disposition.indexOf('attachment') !== -1) {
        let filenameRegex = /filename[^;=\n]=((['"]).*?\2|[^;\n]*)/;
        let matches = filenameRegex.exec(disposition);
        if (matches != null && matches[1]) {
          // 「filename*=UTF-8''%E3%83%87%E3%83%BC%E3%82%BF.txt;」からファイル名を取得
          fileName = decodeURI(matches[1].replace(/['"]/g, '').replace('utf-8', '').replace('UTF-8', ''));
        }
      }
      if (fileName === '') {
        // ファイル名を取得できなかったら念のため URL をファイル名とする
        let fileName = url.match('.+/(.+?)([\?#;].*)?$')[1];
      }

      // Blob オブジェクトを指す URL オブジェクトを作る
      let objectURL = window.URL.createObjectURL(blob);
      // リンク(<a>要素)を生成し、JavaScript からクリックする
      let link = document.createElement('a');
      document.body.appendChild(link);
      link.href = objectURL;
      link.download = fileName;   // download を指定するとブラウザで開くことなくダウンロードになる
      link.click();
      document.body.removeChild(link);

      console.log('ダウンロードを完了しました。');
    }
  };

  // リクエスト開始
  xhr.send();
});

a בדרך כלל, אם תשאיר את הרכיב בלחיצה, תהליך ההורדה המוגדר כברירת מחדל יעבור, ולכן e.preventDefault(); אנו קוראים להשבית את תהליך ברירת המחדל.

href קבל את כתובת האתר להורדה מ והגדר XMLHttpRequest GET אותה כדי לקבל אותה מ .

XMLHttpRequest.responseTypeblob כדי להורות להוריד את הנתונים הבינאריים.

XMLHttpRequest.onload מכיוון שניתן לתאר את התהליך לאחר השלמת הורדת הנתונים באירוע, התהליך לאחר השלמת ההורדה נכתב כאן. מכיוון שהנתונים הורדו רק ללקוח, הקובץ אינו מאוחסן בפועל באופן מקומי. כדי לשמור קובץ באופן מקומי, באפשרותך להוסיף תג המכיל a פסאודו-נתונים ולגרום לו להתנהג כאילו לחצת על קישור ושמרת את הקובץ. הנתונים באותו זמן ניתן window.URL.createObjectURL להמיר לכתובת URL על ידי הפונקציה, כך href שתוכל להגדיר את זה ולגרום לזה לעבוד.

ניתן לאחזר את שם הקובץ שיש לשמור מכותרת התגובה אם הוא כלול בתגובה מהשרת Content-Disposition . מכיוון שזה קצת מסובך לרכוש, אני חושב שצריך להשתמש בקוד כפי שהוא. אם שם הקובץ אינו מצוין בשרת, לא ניתן לעזור לו, לכן אני חושב שהוא יוגדר לשם הקובץ המוגדר כברירת מחדל או לשם הקובץ בסוף נתיב כתובת האתר.

מאז הפעם אני רק להציג אותו במסוף לאחר שמירת הקובץ, אני חושב כי הפעולה הרצויה ניתן לבצע על ידי שכתוב חלק זה עם קוד שרירותי.

לאחר תיאור תהליך הורדת הנתונים, הדבר האחרון שברצוננו לעשות הוא XMLHttpRequest.send לקרוא לפונקציה כדי להתחיל את הבקשה בפועל.

הורד קישור הפעלה

Mr./Ms. Code מספק קישורים לדפוס הורדת הקובץ ישירות ולדפוס הורדתו באמצעות Javascript. a באפשרותך לכתוב את כתובת ה- URL ישירות בתג href , אך אם תכתוב את הפרטים הבאים ב- ASP.NET Core, כתובת ה- URL תתרחב באופן אוטומטי href ל- .

דפי גילוח : Pages/Index.cshtml

<ul>
  <li><a asp-page-handler="Download">ダウンロード (Javascript なし)</a></li>
  <li><a asp-page-handler="Download" id="download">ダウンロード (Javascript あり)</a></li>
</ul>

MVC : צפיות/בית/Index.cshtml

<ul>
  <li><a asp-controller="Home" asp-action="Download">ダウンロード (Javascript なし)</a></li>
  <li><a asp-controller="Home" asp-action="Download" id="download">ダウンロード (Javascript あり)</a></li>
</ul>